getDocument<T> method

Future<NimbostratusDocumentSnapshot<T?>> getDocument<T>(
  1. DocumentReference<T> docRef, {
  2. GetFetchPolicy fetchPolicy = GetFetchPolicy.serverOnly,
  3. NimbostratusFromFirestore<T>? fromFirestore,
})

Retrieves a Firestore document from the in-memory cache or server according to the specified GetFetchPolicy.

Implementation

Future<NimbostratusDocumentSnapshot<T?>> getDocument<T>(
  DocumentReference<T> docRef, {
  GetFetchPolicy fetchPolicy = GetFetchPolicy.serverOnly,
  NimbostratusFromFirestore<T>? fromFirestore,
}) async {
  DocumentSnapshot<T?> snap;

  switch (fetchPolicy) {
    case GetFetchPolicy.cacheFirst:
    case GetFetchPolicy.cacheOnly:
      // First try to read the document from the NS cache, falling back to the Firestore cache.
      final docBloc = _documents[docRef.path];
      if (docBloc != null) {
        try {
          final value = docBloc.value;

          if (value is NimbostratusDocumentSnapshot<T?>) {
            return value;
          }
          return _updateFromRef(reference: docRef, value: null);
        } catch (e) {
          if (kDebugMode) {
            print('Error reading document');
          }
        }
      }

      try {
        // If the data was not available in the Firestore cache, it throws an error.
        // We can then fallback to fetching the data from the server for server-supported fetch policies.
        snap = await docRef.get(const GetOptions(source: Source.cache));

        // The documentation indicates that an exception should be thrown if the document
        // does not exist in the cache.
        if (!snap.exists) {
          throw FirebaseException(plugin: 'missing_document');
        }
        // ignore: empty_catches.
      } catch (e) {
        if (fetchPolicy == GetFetchPolicy.cacheFirst) {
          return getDocument(
            docRef,
            fetchPolicy: GetFetchPolicy.serverOnly,
          );
        } else {
          return _updateFromRef(reference: docRef, value: null);
        }
      }
      return _updateFromSnap(snap);
    case GetFetchPolicy.serverOnly:
      try {
        final snap = await docRef.get();
        return _updateFromSnap(snap, fromFirestore: fromFirestore);
      } catch (e) {
        return _updateFromRef(value: null, reference: docRef);
      }
  }
}