Zeyad
Zeyad

Reputation: 1

Caching for Flutter Firestore collectionGroup

I am in the process of implementing caching for my Flutter/Firebase project. For a regular document get, I often do it as follows:

DocumentSnapshot<Map<String, dynamic>> doc;

try {
    doc = await storeRef.doc(uid).get(GetOptions(source: Source.cache));
} catch (_) {
    doc = await storeRef.doc(uid).get(GetOptions(source: Source.server));
}

This works fine, and it does the job as expected. However, when I tried the same for some of my collectionGroup, it did not work as expected. The collectionGroup results would only contain items that have already been cached, and not the entire collectionGroup.

My code was as follows:

// caching doesn't work with collectionGroup
QuerySnapshot<Map<String, dynamic>> query;

try {
    query = await FirebaseFirestore.instance.collectionGroup("users").where('uid', isEqualTo: uid).get(GetOptions(source: Source.cache));
} catch (_) {
    query = await FirebaseFirestore.instance.collectionGroup("users").where('uid', isEqualTo: uid).get(GetOptions(source: Source.server));
}

This makes sense, but just want to see if anyone got a work around to get it caching values after the first get, instead of pulling from the firestore every time, which is expensive as this specific query is used very often throughout my project.

If nothing works, I may just use a local map as a short-term cache after the first get, although this may not be very efficient or optimized, but it would significantly reduce reads from firestore and save costs.

Upvotes: 0

Views: 40

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 599996

You say:

The collectionGroup results would only contain items that have already been cached, and not the entire collectionGroup.

That makes sense. Since you tell Firestore to get the query results from its local cache, all it returns are results from the local cache.

If you want it to retrieve up-to-date results from the server, you should stop telling it to return only results from its local cache. At that point you'll pay for those document reads on the server, because the only way for Firestore to determine if the document has changed is to actually read it.


Your application may be able to do better though. For example, I often:

  1. add a lastUpdated field to my documents, which I set on every write.
  2. track the timestamp of when the client last read from the server in a local storage variable in the app.
  3. then can do a query to just get document that were modified after the last read time from the server.

This complicates the code, but will save you the document reads that you want to avoid.


The behavior is not specific to a collection group btw, but applies to all multi-document reads

Upvotes: 0

Related Questions