I am running into a firestore issue that I hope someone can help me out with.
I have an active document snapshot listener that seems to be breaking sorting behavior, and I'm not sure why.
In the constructor of my component, I initialize the document snapshot listener once:
this.listen = this.fs.collection('users').doc('0EwcWqMVp9j0PtNXFDyO').ref.onSnapshot(t => {
console.log(t)
})
Whenever I click the Sort button it initializes a new collection query which is sorted by first name.
async onSort() {
if (this.first) {
this.first();
}
this.sort = this.sort === 'asc'? 'desc' : 'asc';
alert(this.sort)
let arr = []
let lastDoc = null
let queryRef = this.fs.firestore.collection('users').orderBy('firstName', this.sort as any).limit(20);
this.users$ = this._users$.asObservable()
// initialize a blank list
this._users$.next([])
// subscribe to user list snapshot changes
const users1: { users: any, last: any } = await new Promise((resolve, reject) => {
this.first = queryRef.onSnapshot((doc) => {
console.log("Current data: ", doc);
const users = doc.docs.map(t => {
return {
id: t.id,
...t.data() as any
}
})
console.log(users)
resolve({
users: users,
last: doc.docs[doc.docs.length -1]
})
});
})
this._users$.next(this._users$.value.concat(users1.users))
}
However, this is not working as expected. The sort is returning one record (there should be 20 records, based on the limit).
Interestingly, unsubscribing from the document snapshot, fixes the sorting. 20 records are being returned and the sorting is behaving correctly.
Can someone please explain what I am doing wrong?
Here is a minimal Stackblitz that reproduces the issue.
[Edit]
Getting closer to a solution and an understanding... Thanks to @ZackReam for the explanation and both @Robin and @Zack for the the canonical answers.
It seems that this._firestore.firestore.collection('users').orderBy('firstName', this.sort as any).limit(20).onSnapshot(...) is indeed emitting twice - once for the active document listener (which has 1 record in the cache), and a second time for the sorted collection (which is not in the cache since switchMap will unsubscribe everytime that the sort is executed).
We can see that briefly in the functional demo that Zack posted - it flashes with one record corresponding to the document listener, then an instant later, the list is populated with the sorted collection.
The more active listeners you have, the weirder the flashes of results will be. Is this by design? seems flawed to me...
Intuitively, I would expect snapshotChanges() or valueChanges() from the this._firestore.firestore.collection('users').orderBy('firstName', this.sort as any).limit(20) query to return 20 results (the first 20 when sorted), independent of any other document listeners. It's counter-intuitive that the first snapshot from this query is the initial active document from the document query - which should have nothing to do with the sort query.



