nuxt-community / firebase-module

🔥 Easily integrate Firebase into your Nuxt project. 🔥
https://firebase.nuxtjs.org
MIT License
641 stars 99 forks source link

Firebase objects are changed when get is called within AsyncData #511

Closed ginogottini closed 3 years ago

ginogottini commented 3 years ago

`async asyncData ({app}) {

let courses = []
let limit = 10
let start

let db = app.$fire.firestore
  db = db.collection('courses')
  .orderBy('score', 'desc')
  .limit(limit)

await db.get()
.then(snaps => { 
  if (!snaps.empty) {
  snaps.forEach(doc => {
    let course = doc.data()
    course.id = doc.id
    courses.push(course)
  })
  start = snaps.docs[snaps.docs.length - 1]
  }
})

return { courses start}`

If this is called in AsyncData I am unable to get the last document correctly to use for pagination with STARTAFTER

console.log(start)

QueryDocumentSnapshot$2 { _delegate: QueryDocumentSnapshot$1 { _firestore: FirebaseFirestore$1 { _persistenceKey: '[DEFAULT]', _settings: [FirestoreSettings], _settingsFrozen: true, _app: [FirebaseAppImpl], _databaseId: [DatabaseId], _credentials: [FirebaseCredentialsProvider], _queue: [AsyncQueueImpl], _firestoreClient: [FirestoreClient] }, _userDataWriter: UserDataWriter { firestore: [Firestore] }, _key: DocumentKey { path: [ResourcePath] }, _document: Document { key: [DocumentKey], version: [SnapshotVersion], objectValue: [ObjectValue], hasLocalMutations: false, hasCommittedMutations: false }, _converter: null, _firestoreImpl: FirebaseFirestore$1 { _persistenceKey: '[DEFAULT]', _settings: [FirestoreSettings], _settingsFrozen: true, _app: [FirebaseAppImpl], _databaseId: [DatabaseId], _credentials: [FirebaseCredentialsProvider], _queue: [AsyncQueueImpl], _firestoreClient: [FirestoreClient] }, metadata: SnapshotMetadata { hasPendingWrites: false, fromCache: false } }, _firestore: Firestore { _delegate: FirebaseFirestore$1 { _persistenceKey: '[DEFAULT]', _settings: [FirestoreSettings], _settingsFrozen: true, _app: [FirebaseAppImpl], _databaseId: [DatabaseId], _credentials: [FirebaseCredentialsProvider], _queue: [AsyncQueueImpl], _firestoreClient: [FirestoreClient] }, _persistenceProvider: IndexedDbPersistenceProvider {}, INTERNAL: { delete: [Function: delete] }, _appCompat: FirebaseAppImpl { firebase_: [Object], isDeleted_: false, name_: '[DEFAULT]', automaticDataCollectionEnabled_: false, options_: [Object], container: [ComponentContainer] } } }

If I call the same method in CREATED/MOUNTED it works correctly.

console.log(start)

e {__ob__: Observer} Yf: (...) d_: (...) exists: (...) id: (...) metadata: (...) ref: (...) __ob__: Observer {value: e, dep: Dep, vmCount: 0} get Yf: ƒ reactiveGetter() set Yf: ƒ reactiveSetter(newVal) get d_: ƒ reactiveGetter() set d_: ƒ reactiveSetter(newVal) __proto__: Ss

It also works correctly if used in ASYNCDATA if navigating to the page. But if loading for the first time or reloading it returns the QueryDocumentSnapshot$2 which I am unable to use with STARTAFTER.

The incorrect object

1

The correct object

2

My current fix is to get the last object with its ID in CREATED.

tibs245 commented 3 years ago

snaps is not array. ForEach is special Firebase function. This for that start = snaps.docs[snaps.docs.length - 1] not work

But why you don't use courses[courses.length -1] ?

ginogottini commented 3 years ago

I just tried using courses[courses.length -1] but startAfter() doesn't get the correct objects. When using the doc.data() object it is not the same as the snaps.docs[index] object.

snaps.docs[snaps.docs.length - 1] e {__ob__: Observer} Yf: e d_: e exists: true id: "0pEbvhvQlv8aVFtI1xmi" metadata: t ref: e __ob__: Observer {value: e, dep: Dep, vmCount: 0} get Yf: ƒ reactiveGetter() set Yf: ƒ reactiveSetter(newVal) get d_: ƒ reactiveGetter() set d_: ƒ reactiveSetter(newVal) __proto__: Ss

courses[courses.length-1] { slug: 'hello-course', company: 'Hello Courses', price: '', verified: 1, updatedAt: 1617933514955, createdAt: 1617769911034, countries: [ 'Vietnam', 'Online' ], score: 4.484745245641387, ratingOverall: 4.95, id: '0pEbvhvQlv8adddi' }

If it helps, in another collection I want to get a document and then update it. But I am unable to do it because of the same issue.

get().then(doc => { doc.ref.update({ }) })

I am unable to update it as expected because ref is not as it should be.

tibs245 commented 3 years ago

Ok, you want really snapshot and not the data for update

If you create courses Array with data And coursesSnapshot with snapshot corresponding ?

Or object courses { data: , snapshotDocument: }

ginogottini commented 3 years ago

Thanks for suggestion. I tried it, but still cannot get the doc.ref

tibs245 commented 3 years ago

Can you reproduce a example of your situation in a Code Pen simplified ?

lupas commented 3 years ago

Hey guys

These are regular Firebase questions not related to this module (or Nuxt) at all. Please use https://stackoverflow.com/ for such questions in the future, since this issue board is used for module specific issues and bugs.

Thanks a lot - appreciate it!

ginogottini commented 2 years ago

This is a nuxt issue.

Solution here: https://github.com/nuxt/nuxt.js/issues/6480