0
votes

I'm trying to clarify the semantics of Firestore query snapshot updates in the face of changing documents. The "Listen to multiple documents in a collection" doc says:

The snapshot handler will receive a new query snapshot every time the query results change (that is, when a document is added, removed, or modified).

My question is if a document that was already in the snapshot is updated, will it always trigger a new query snapshot? Even if the change to the document has nothing to do with the original query? Is this documented somewhere? (Specifically, what is the definition of "query results change"?)

Consider a case with several existing documents in a collection. Start by querying for all the documents, for example:

db.collection("cities").onSnapshot(snapshot => { ... })

Now if a new document is created in the collection, or a document is removed, the onSnapshot callback will be re-invoked with those changes because the "query results" are different.

But what happens if a document in that example collection is modified after the initial onSnapshot callback is invoked? (E.g., a new property is added to one of the "cities" documents.) Will the onSnapshot callback always be invoked to report this modified document? Does this count as changing the "query results"? The set of documents returned is not different, so it seems like this sort of change might not be reported in the collection query?

In truth I'm seeing some odd behavior in my application, and I'm trying to double-check what the semantics of onSnapshot collection updates are intended to be. In comparison, the documentation for single-document onSnapshot semantics is clearer about reporting all content changes:

An initial call using the callback you provide creates a document snapshot immediately with the current contents of the single document. Then, each time the contents change, another call updates the document snapshot.

But I cannot find similar clarity for the collection snapshot documentation.

1

1 Answers

1
votes

My question is if a document that was already in the snapshot is updated, will it always trigger a new query snapshot? Even if the change to the document has nothing to do with the original query?

There are three cases:

  1. The update to the document doesn't change the fact that the document is returned by the query. In this case, the snapshot handler will receive a new query snapshot which will contain the updated document. So, even if "the set of documents returned is not different" the snapshot handler will receive a new query snapshot.

Example: Your query is db.collection("cities").where("state", "==", "CA").onSnapshot(snapshot => { ... }) and you only change the city name, for example, or a new property is added.

  1. The update to the document removes the document from the query results. In this case, the snapshot handler will receive a new query snapshot without the updated document.

Example: Your query is db.collection("cities").where("state", "==", "CA").onSnapshot(snapshot => { ... }) and you change the state to a value different than CA.

  1. The update to the document includes the document to the query results. In this case, the snapshot handler will receive a new query snapshot containing a new document, the updated one.

Example: Your query is db.collection("cities").where("state", "==", "CA").onSnapshot(snapshot => { ... }) and you change the state value to the CA.


When looking at the doc excerpt:

The snapshot handler will receive a new query snapshot every time the query results change (that is, when a document is added, removed, or modified).

Case 1 above corresponds to "modified", Case 2 to "removed" and Case 3 to "added".