Gaurav Singh
Gaurav Singh

Reputation: 125

Android Firebase database transaction

  ATNRef= FirebaseDatabase.getInstance().getReference("AvailableTokenNumber");
                ATNRef.runTransaction(new Transaction.Handler() {
                    @Override
                    public Transaction.Result doTransaction(MutableData mutableData) {

                        if (mutableData.getValue(int.class ) == 0){
                            mutableData.setValue(2);
                            data.tokenNo = 1;
                            return Transaction.success(mutableData);

                        }else {
                            data.tokenNo=mutableData.getValue(int.class);
                            mutableData.setValue(data.tokenNo + 1);
                            return Transaction.success(mutableData);
                        }
                    }

Whenever the code is run for first time, value of data.tokenNo is 0. After that it is updating correctly as per the database value.

I am not able to figure it out what makes the value of data.token = 0 on every first run of the app/code.

Upvotes: 3

Views: 4169

Answers (2)

wf9a5m75
wf9a5m75

Reputation: 6158

Thank you for explaining, @Doug Stevenson. I understand this situation from your answer.

Then I solved this problem with this. This works for me at least.

FirebaseDatabase database = FirebaseDatabase.getInstance();
try {
    database.setPersistenceEnabled(true);
} catch (Exception e) {
    // ignore
}

...

DatabaseReference ref = database.getReference("somewhere");

// Read value from database to synchronize localDB with remoteDB
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

    // Then execute transaction.
    ref.runTransaction(new Transaction.Handler() {
      @NonNull
      @Override
      public Transaction.Result doTransaction(@NonNull MutableData mutableData) {
        ...
        return Transaction.success(mutableData);
      }


      @Override
      public void onComplete(@Nullable DatabaseError databaseError, boolean committed, @Nullable DataSnapshot dataSnapshot) {
        ...
      }

    });
  }
});

Upvotes: 1

Doug Stevenson
Doug Stevenson

Reputation: 317760

You should be expecting that the initial snapshot of data available in your transaction could be null during its first execution. Note this from the documentation:

Note: Because doTransaction() is called multiple times, it must be able to handle null data. Even if there is existing data in your remote database, it may not be locally cached when the transaction function is run, resulting in null for the initial value.

Also in the javadoc it says:

This method will be called, possibly multiple times, with the current data at this location.

Expect that the first time your handler is run, it will be dealing with an empty database. Then, when the data there is known (if any), you should be prepared to handle that case also. If you don't want to do anything where there is no data (or unknown data) at the location, simply return a successful Transaction with no changes to mutableData.

Upvotes: 5

Related Questions