Search code examples
firebaseflutterdartgoogle-cloud-firestore

Writing to FireStore - how to show error when fails (if no network)


I'm writing data to Firestore Using this function - which works perfectly

  Future<void> validateForm() async {
    try {
      await FirebaseFirestore.instance.collection('collectionPath').add({
        'full_name': 'John Doe',
        'company': 'Stokes and Sons',
        'age': '42',
      });
      ScaffoldMessenger.of(context).showSnackBar(successSnackBar);
    } catch (e) {
      print(e.toString());
      ScaffoldMessenger.of(context).showSnackBar(errorSnackBar);
    }
  }

but I'm trying to display a SnackBar when data can't be written to FireStore

  • currently if I switch my simulator to Airplane Mode the successSnackBar does not show - which is what I want

But I would also like the errorSnackBar to pop-up too which does not happen


Solution

  • Not having a network connection to the backend is not an error condition for Firestore clients. In such situations they simply commit the write locally, fire all necessary events, and synchronize up with the server once a connection is available.

    So the usual order of events is:

    • You make a call that writes
    • The write is performed locally synchronously (meaning that when the add() call returns, the data is written locally - even before the Future completes).
    • Events are fired locally for the new document, with the metadata indicating that the document snapshot has pending writes in it.
    • .... time passes...
    • The write is committed to the server, which also resolves the Future and makes your await statement complete.
    • If needed, local events are fired again with the updated metadata - or to update the actual data in case the server rejected the write.

    The only times your catch will get called is actually when that local write operation fails, or when the write gets rejected on the server (typically because it violates your security rules). In all other cases, there is (intentionally) no error thrown.

    You have a few options:

    • Instead of the await you could implement a time-out mechanism to determine if the call to the server is taking longer than what seems reasonable to you.
    • You could check whether the user has a network connection, and alert them in that case.
    • You could visualize the status of each document in line, instead of with reactive snackbars, based on the hasPendingWrites and isFromCache properties in its SnapshotMetadata object.