getDocuments static method

Future<QuerySnapshot> getDocuments({
  1. required Query query,
  2. required DocumentReference cacheDocRef,
  3. required String firestoreCacheField,
  4. String? localCacheKey,
  5. bool isUpdateCacheDate = true,
})

Fetch documents with read read from cache first then server.

This method takes in a query which is the usual Firestore Query object used to query a collection, and a cacheDocRef which is the DocumentReference object of the document containing a firestoreCacheField field of timestamp. You can also pass in localCacheKey as the key for storing the last local cache date, and isUpdateCacheDate to set if it should update the last local cache date to current date and time.

Implementation

static Future<QuerySnapshot> getDocuments({
  required Query query,
  required DocumentReference cacheDocRef,
  required String firestoreCacheField,
  String? localCacheKey,
  bool isUpdateCacheDate = true,
}) async {
  localCacheKey = localCacheKey ?? firestoreCacheField;

  final isFetch = await isFetchDocuments(
    cacheDocRef,
    firestoreCacheField,
    localCacheKey,
  );
  final src = isFetch ? Source.serverAndCache : Source.cache;
  var snapshot = await query.get(GetOptions(source: src));

  // If it is triggered to get documents from cache but the documents do not exist,
  // which means documents may have been removed from cache,
  // we then fallback to default get documents behavior.
  if (src == Source.cache && snapshot.docs.isEmpty) {
    snapshot = await query.get();
  }

  // If it is set to update cache date, and there are documents in the snapshot, and
  // at least one of the documents was retrieved from the server,
  // update the latest local cache date.
  if (isUpdateCacheDate &&
      snapshot.docs.isNotEmpty &&
      snapshot.docs.any((doc) => doc.metadata.isFromCache == false)) {
    var prefs = await SharedPreferences.getInstance();
    await prefs.setString(localCacheKey, DateTime.now().toIso8601String());
  }

  return snapshot;
}