Home > Software design >  Why does persistenceEnabled: true result in my queries giving incorrect results?
Why does persistenceEnabled: true result in my queries giving incorrect results?

Time:04-04

I am using Firestore in my Flutter app. When I query a collection, I am getting the incorrect number of documents back.

The correct number of documents I should be getting back for my query is 20.

If I initialise Firebase as follows...

await Firebase.initializeApp();
FirebaseFirestore.instance.settings = Settings(persistenceEnabled: true);

I get only 2 documents back from my query.

If I initialize Firebase with peristenceEnabled false...

await Firebase.initializeApp();
FirebaseFirestore.instance.settings = Settings(persistenceEnabled: false);

I am wondering if it has to do with the fact I am only grabbing the first event in the stream. My query is as follows...

 static Future<List<String>> myQuery(String personId , String bagId , String batchId , List<String> items) async {
    var db = FirebaseFirestore.instance;
    var q = db.collection('people')
          .doc(personId)
          .collection('bags')
          .doc(bagId)
          .collection('batches')
          .where('batchId', isEqualTo: batchId)
          .where('itemId', whereIn: items)
          .where('status', isEqualTo: 'active');
    var stream =  q.snapshots().map((snapshot) {
      List<String> results = [];
      for (var doc in snapshot.docs) {
        results.add(doc.id);
      }
      return results;
    });

    return stream.first;
  }
}

If persistence is enabled this method returns a list of incorrect length. If persistence is disabled, this returns a list of the correct length.

I would expect the built in firestore caching mechanism would be smart enough to detect that any cached data is stale. I am therefore wondering if there is something wrong with my firestore data in general, such that it is breaking client side persistence/caching.

CodePudding user response:

If you call snapshots() on a query, the Firestore SDK immediately invoked your callback with whatever data it has in the cache for that query (if any). It then checks with the server for any updates to the data, and (if any) invokes you callback again with the latest data.

But since you then call first() on the stream, you are only getting that first data from the local cache, and not the data from the server. If you only care about the current data, you should use get() instead of snapshots(), as that will first check for updates from the server before it invokes your callback.

So:

var snapshot = await q.get();

List<String> results = snapshot.map((doc) {
  return doc.id;
});

return results;
  • Related