Reputation: 125
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
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
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