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);
}
}
每当第一次运行代码时,data.tokenNo的值为0。 之后,它根据数据库值正确更新。
我无法弄清楚每次首次运行app / code时data.token = 0的值是什么。
答案 0 :(得分:4)
您应该期望事务中可用数据的初始快照在首次执行时可能为空。请注意the documentation:
注意:因为多次调用doTransaction(),所以必须这样做 能够处理空数据。即使您的现有数据存在 远程数据库,它可能不会在事务时本地缓存 函数运行,导致初始值为null。
同样在javadoc中说:
此方法将使用当前调用,可能多次 这个位置的数据。
预计第一次运行处理程序时,它将处理一个空数据库。然后,当已知数据(如果有的话)时,您应该准备好处理该情况。如果您不希望在该位置没有数据(或未知数据)的情况下执行任何操作,只需返回成功的Transaction,而不更改mutableData。
答案 1 :(得分:0)
@Doug Stevenson,谢谢您的解释。 我从您的回答中了解这种情况。
然后我用这个解决了这个问题。 这至少对我有用。
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) {
...
}
});
}
});