I am working with AngularFire2 in my project. I have a service as follows
getItems(thing: string): Observable<Item[]> {
return this.db.collections('item', ref => ref.where('things', 'array-contains', thing))
.valuechanges({ idField: 'id' })
}
I then subscribe to the service
this.itemService.pipe(take(1)).subscribe(res => console.log(res));
I am using take(1) both for the value of finishing the subscription but also because I don't want the values to emit again upon changes.
I have noticed that with this service I get intermittently incomplete results. For instance, I will sometimes get
[{id: 1, name:widget}, {id:2, name: whatsit}]
And other times, I will get
[{id: 1, name:widget}]
With no changes to the db. I have worked around this problem using
getItems(thing: string): Observable<Item[]> {
return this.db.collections('item', ref => ref.where('things', 'array-contains', thing))
.get().pipe(map(res => res.docs.map(
doc => ({id: doc.id, ...doc.data()} as Item))))
}
However, it seems like a lot of extra code. I guess I am not understanding why the first emitted value of valueChanges can be incomplete.
If there is pre-existing observer of document(s) that are returned by query, firestore will first emit locally available results and then results gotten from running query against server.
So if earlier in your code you had:
this.db.collections('item', ref => ref.where('name', 'equals', widget)) .valuechanges().subscribe()
Then you would see behavior you were reporting , where first emission would contain only [{id: 1, name:widget}] and second would contain [{id: 1, name:widget}, {id:2, name: whatsit}]. This is true irregardless of whether local persistence is enabled.