I have an app which maintains a full copy of user data locally, but it needs to get updates from firestore when any data has been changed remotely. To achieve this, I include a serverTimestamp as a field for all database documents, like so:
updateDoc(myDoc, { ...otherFields, lastUpdated: serverTimestamp() });
And then I have a snapshot listener to get updates. I check the timestamp on each document and save the most recent one for future queries (if lastTimestamp is null, I query for all documents).
let q = query(myCollection, where("lastUpdated", ">", lastTimestamp));
onSnapshot(q, (s) => s.docChanges().forEach((change) => {
/*...*/
if(lastTimestamp.valueOf() < change.doc.data().lastUpdated.valueOf()) {
lastTimestamp = change.doc.data().lastUpdated;
}
});
The issue is that my query doesn't seem to work--the snapshot does not get triggered on updates. Apparently my where("lastUpdated", ">", lastTimestamp) is not processed correctly, since it work fine if I leave that out (to query for all documents--not a permanent solution). Is there a correct way to query for documents based on a serverTimestamp field that I am missing?
The problem, in my case, was that I had saved lastUpdated to localStorage and loaded it, stripping it of its type information. So instantiating a Timestamp (import { Timestamp } from "firebase/firestore") solved the problem for me:
const ts = lastUpdatedFromLocalStorage;
if(ts) lastUpdated = new Timestamp(ts.seconds, ts.milliseconds);
else lastUpdated = null;