Search code examples
flutterdartgoogle-cloud-firestorepersistence

Flutter cloud_firestore persistence is not working even if it is enabled


I've done tons of searches on this. But, my flutter app is working nice on the active network. I've enabled persistence for cloud_firestore, but it's showing this error:

[cloud_firestore/unavailable] The service is currently unavailable. This is a most likely a transient condition and may be corrected by retrying with a backoff.

My sample code:

FirebaseFirestore db = FirebaseFirestore.instance;
  db.settings = Settings(persistenceEnabled: true, cacheSizeBytes: 10000000);

final ref = db.doc("some_collection/some_doc");

try{
  ref.update({"key": value});
} catch(error) {
  print(error.toString());
}

My pubspec.yaml:

firebase_messaging: ^8.0.0-dev.14
firebase_core: ^0.7.0
firebase_auth: ^0.20.0+1
flutter_local_notifications: ^3.0.3
cloud_firestore: ^0.16.0

Solution

  • So, my scenario was, I had to upload some data to firestore whenever my application receives an incoming message from my client. That's why I needed two services, one is background message receiver and firestore persistence.

    What I was doing:

    Trying to read some data from the firestore first and based on that I need to put the incoming message data to the firestore again. Something like this:

    FirebaseFirestore db = FirebaseFirestore.instance;
    db.settings = Settings(persistenceEnabled: true, cacheSizeBytes: 10000000);
    
    // payments ref
    final paymentRefs = db
         .collection("payments")
         .where("trxID", isEqualTo: "123456")
         .where("amount", isEqualTo: 50)
         .limit(1);
    
    try {
       final paymentGet = await paymentRefs.get();
         if (paymentGet.size > 0) {
           final paymentData = paymentGet.docs[0];
           // check for payment existence with the trxID
           // if exists, then validate and update
           if (paymentData.exists) {
            final paymentAmount = paymentData.data()['amount'];
            final exactPaymentRef = db.collection("payments").doc(paymentData.id);
    
             // for individual and if amount matches
             if (amount == paymentAmount) {
                exactPaymentRef.update({
                  "paid": true
                });
             }
          } else {
            // payment ref not found with trxID
            // so upload the trxID to reqTrxID collection
            db.doc("reqTrxID/$trxID").set({
              "createdAt": new DateTime.now().millisecondsSinceEpoch,
              "phoneNumber": phoneNumber,
              "amount": amount
            });
         }
      }
    } catch (error) {
        print("error triggering to firestore: ${error.toString()}");
    }
    

    My mistake was, I was doing some extra fetchings from the firestore. And as firebase documentation firestore persistence won't work on any asynchronous (try/catch, promise, async/await) way (that I was doing so happily :) ).

    How I solved this:

    FirebaseFirestore db = FirebaseFirestore.instance;
    
      db.doc("reqTrxID/$trxID").set({
        "createdAt": new DateTime.now().millisecondsSinceEpoch,
        "phoneNumber": phoneNumber,
        "amount": amount
      });
    

    I simply just upload the value I had to, and my all necessary checking I send them to cloud function on document create trigger. That's solved my problem.