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
I think firestore plugin already take care of what you want to achieve, See Questions about firestore cache and reads charge
I’d probably:
LocalRepositoryManager.itemCacheDate
value every time you get an updated snapshot from the server.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.