skip to Main Content

I am trying to reduce the number of firestore reads by reading from my cache first and then creating a subscription listener based on the lastCacheDate in my cache.

This all works great as long as the app is closed and then reopened, because the subscription is rebuilt. When the app is left open, but not used, the app will read from the server for all new items using the old lastCacheDate the next time it is opened. Is there a different way I should create the subscription or listener or is there a trigger or a way to know the listener is not active? Then I could maybe close the listener and create a new listener with the new lastCacheDate in the cache.

I don’t have the option on using StreamBuilder or other widgets, this code is all happening in a provider. Any help would be appreciated.

One thing I haven’t tried is to use the WidgetsBindingObserver and figure out how long the app has been inactive, then if it is longer than 30 minutes, close the subscription and reopen with new lastCacheDate when it is resumed. Seems like there should be a better way than that though.

    _initializeData() {
        String CollectionKey = 'collection1';
        String UidKey = 'uidKey';
        String uid = 'uid1';
    
        //query the cache first
        var ref = FirebaseFirestore.instance
            .collection(CollectionKey)
            .where(UidKey, isEqualTo: uid);
        var docSnap = await ref.get(const GetOptions(source: Source.cache));
        for (final document in docSnap.docs) {
            _fireLog.info('Retrieved cache document');
            _processDoc(document.data());
        }
    
        //create a subscription to listen for new items
        _allItemsSubscription = FirebaseFirestore.instance
            .collection(CollectionKey)
            .where(UidKey, isEqualTo: uid)
            .where(ItemInterface.ModifiedDateKey,
                    isGreaterThan: LocalRepositoryManager.itemCacheDate)
            .snapshots()
            .listen((snapshot) {
                    for (final document in snapshot.docs) {
                    _fireLog.info('Retrieved server document');
    
                    // this processDoc will set the LocalRepositoryManager.itemCacheDate
                    _processDoc(document.data());
                    }
                    }
            );
    }

2

Answers


  1. I think firestore plugin already take care of what you want to achieve, See Questions about firestore cache and reads charge

    Login or Signup to reply.
  2. I’d probably:

    1. Update the LocalRepositoryManager.itemCacheDate value every time you get an updated snapshot from the server.
    2. Then cancel the existing listener.
    3. And start a new one.

    That way you’re always listening for data that the client doesn’t have in its cache yet. That should minimize the number of document read charges.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search