admin管理员组

文章数量:1124171

I have a flutter app where I have a Stream<DocumentSnapshot<Map<String, dynamic>>>? listening to a users account in my Firebase Firestore database.

I ran into an issue when testing my app offline (in airplane mode). When I would call a function to edit my account in firebase (for example):

in my State Notifier Provider:

    state = state.copyWith(accountStatus: AccountStatus.loading);
    try {
      await read<AccountService>()
          .exampleFunc();
    state = state.copyWith(accountStatus: AccountStatus.loaded);
    } on CustomError catch (e) {
      state = state.copyWith(
          accountStatus: AccountStatus.error, customError: e);
      if (context.mounted) {
        errorDialog(context, e);
      }
      rethrow;
    }

exampleFunc() in AccountService:

try {
      await firebaseReferenceHere.update({data});
    } on FirebaseException catch (e) {
      throw CustomError(
        code: e.code,
        message: e.message!,
        plugin: e.plugin,
      );
    } catch (e) {
      throw CustomError(
        code: 'Exception',
        message: e.toString(),
        plugin: 'flutter_error/server_error',
      );
    }

My account data would update immediately via my stream (the data is properly being cached), however my function would only finish after I connected back to the internet (thus leaving my account state as AccountStatus.loading until then).

Referencing this question: Using Offline Persistence in Firestore in a Flutter App I found that removing await from inside of AccountService allowed my function to complete offline.

My issue is, however, that for a function like updating a user's profile picture I first have to write to Firebase Storage, and then get the Storage url before updating my Firestore user data.

await firebaseReferenceHere.putFile(profilePicFile);
url = await firebaseReferenceHere.getDownloadURL();
return url;

Once I have the url I update my account like above. The function stalls and waits for an internet connection at putFile(). From my console I see:

W/ExponenentialBackoff( 5671): network unavailable, sleeping.

W/StorageUtil( 5671): Error getting App Check token; using placeholder token instead. Error: com.google.firebase.FirebaseException: No AppCheckProvider installed.

First Question: Is removing await from writing to Firestore even a proper solution for the first example?

Second Question: How can I deal with my update profile picture example offline (requiring a return url from Firebase Storage before writing to Firestore)?

I have a flutter app where I have a Stream<DocumentSnapshot<Map<String, dynamic>>>? listening to a users account in my Firebase Firestore database.

I ran into an issue when testing my app offline (in airplane mode). When I would call a function to edit my account in firebase (for example):

in my State Notifier Provider:

    state = state.copyWith(accountStatus: AccountStatus.loading);
    try {
      await read<AccountService>()
          .exampleFunc();
    state = state.copyWith(accountStatus: AccountStatus.loaded);
    } on CustomError catch (e) {
      state = state.copyWith(
          accountStatus: AccountStatus.error, customError: e);
      if (context.mounted) {
        errorDialog(context, e);
      }
      rethrow;
    }

exampleFunc() in AccountService:

try {
      await firebaseReferenceHere.update({data});
    } on FirebaseException catch (e) {
      throw CustomError(
        code: e.code,
        message: e.message!,
        plugin: e.plugin,
      );
    } catch (e) {
      throw CustomError(
        code: 'Exception',
        message: e.toString(),
        plugin: 'flutter_error/server_error',
      );
    }

My account data would update immediately via my stream (the data is properly being cached), however my function would only finish after I connected back to the internet (thus leaving my account state as AccountStatus.loading until then).

Referencing this question: Using Offline Persistence in Firestore in a Flutter App I found that removing await from inside of AccountService allowed my function to complete offline.

My issue is, however, that for a function like updating a user's profile picture I first have to write to Firebase Storage, and then get the Storage url before updating my Firestore user data.

await firebaseReferenceHere.putFile(profilePicFile);
url = await firebaseReferenceHere.getDownloadURL();
return url;

Once I have the url I update my account like above. The function stalls and waits for an internet connection at putFile(). From my console I see:

W/ExponenentialBackoff( 5671): network unavailable, sleeping.

W/StorageUtil( 5671): Error getting App Check token; using placeholder token instead. Error: com.google.firebase.FirebaseException: No AppCheckProvider installed.

First Question: Is removing await from writing to Firestore even a proper solution for the first example?

Second Question: How can I deal with my update profile picture example offline (requiring a return url from Firebase Storage before writing to Firestore)?

Share Improve this question edited yesterday DarkBee 15.8k8 gold badges69 silver badges110 bronze badges asked 2 days ago greenzebragreenzebra 5751 gold badge7 silver badges24 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

As you discovered: the Firestore SDK caches offline writes locally immediately, but only resolves the Future it returns once the write is committed on the server (hence needing to remove await). Removing the await means that you don't want the local client to wait until the remote write is completed, which seems to be exactly the offline behavior you want.


No such offline support exists in the Firebase SDK for Cloud Storage however. If there is no connection, the upload simply times out and/or fails (depending on config and system).

To allow the user to schedule an upload while they're offline, you'll have to implement such scheduling yourself. So:

  1. Detect that the user is offline
  2. Write the upload request to a database (you could even use Firestore for that)
  3. When you detect that the user comes back online:
    1. Process the pending upload requests
    2. Update the corresponding Firestore documents

If you want to learn more about this behavior and offline behavior of other Firebase products, I recommend watching Firebase offline: What works, what doesn't, and what you need to know. It's a few years old, but mostly still applies.

本文标签: flutterHow can I manage write to Firestore and Cloud Storage while offlineStack Overflow