Search code examples
flutterfirebase-realtime-databaseoffline

How can I do an offline batch in Firebase RTDB?


I have reason to believe that some ServerValue.increment() commands are not executing.

In my App, when the user submits, two commands are executed:

Future<void> _submit() async {
    alimentoBloc.descontarAlimento(foodId, quantity);
    salidaAlimentoBloc.crearSalidaAlimento(salidaAlimento);
}

The first command updates the amount of inventory left in the warehouse (using ServerValue.increment)...

 Future<bool> descontarAlimento(String foodId, int quantity) async {
    try {
      dbRef.child('inventory/$foodId/quantity')
        .set(ServerValue.increment(-quantity));
    } catch (e) {
      print(e);
    }
   return true;
  }

The second command makes a food output register, where it records the quantity, type of food and other key data.

  Future<bool> crearSalidaAlimento(SalidaAlimentoModel salidaAlimento) async {

    try {
      dbRef.child('output')
        .push().set(salidaAlimento.toJson());
    } catch (e) {
      print(e);
    }
    return true;
  }

After several reviews, I have noticed that the increase command is not executed sometimes, and then the inventory does not correspond to what it should be.

Then, I would like to do something similar to a transaction, this is: If neither of the two commands is executed, do not execute either of the two.

Is it possible to do a batch of commands in Firebase Realtime without losing the offline functionalities?


Solution

  • You can do a multi-path update to perform both writes transactionally:

    var id = dbRef.push().key;
    Map<String, dynamic> updates = {
      "inventory/$foodId/quantity": ServerValue.increment(-quantity),
      "output/$id": salidaAlimento.toJson()
    }
    dbRef.update(updates);
    

    With the above, either both writes are completed, or neither of them is.

    While you're offline, the client will fire local events based on its best guess for the current value of the server (which is gonna be 0 if it never read the value), and it will then send all pending changes to the server when it reconnects. For a quick test, see https://jsbin.com/wuhuyih/2/edit?js,console