Android Firebase数据库事务
每当代码第一次运行时,data.tokenNo的值为0。 之后,它将根据数据库值正确更新Android Firebase数据库事务,android,firebase,firebase-realtime-database,Android,Firebase,Firebase Realtime Database,每当代码第一次运行时,data.tokenNo的值为0。 之后,它将根据数据库值正确更新 我无法理解是什么使data.token的值在每次应用程序/代码的第一次运行时都为0。您应该期望事务中可用数据的初始快照在第一次执行时可能为空。请注意: 注意:由于doTransaction()被多次调用,因此必须 能够处理空数据。即使您的数据库中存在现有数据 远程数据库,当事务发生时,它可能不会在本地缓存 函数运行,导致初始值为null 此外,报告还说: 此方法将使用当前 此位置的数据 第一次运行处理程序时
我无法理解是什么使data.token的值在每次应用程序/代码的第一次运行时都为0。您应该期望事务中可用数据的初始快照在第一次执行时可能为空。请注意: 注意:由于doTransaction()被多次调用,因此必须 能够处理空数据。即使您的数据库中存在现有数据 远程数据库,当事务发生时,它可能不会在本地缓存 函数运行,导致初始值为null 此外,报告还说: 此方法将使用当前 此位置的数据
第一次运行处理程序时,它将处理一个空数据库。然后,当那里的数据已知时(如果有的话),您也应该准备好处理这种情况。如果您不想在该位置没有数据(或未知数据)的情况下执行任何操作,只需返回一个成功的事务,而不更改可变数据。谢谢您的解释,@Doug Stevenson。 我从你的回答中了解到这种情况 然后我用这个解决了这个问题。 这至少对我有用
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);
}
}
这起作用了。但这些数据并没有得到实时反映。从数据库检索数据时,最初显示为0。与UI元素进行某些交互(如按下按钮或继续)后,“0”将更改为数据库中的实际值。这种情况不仅发生在第一次访问数据库时,而且发生在每次检索数据时。如何避免这种情况?实际数据如何在第一时间显示出来?我不知道你的意思。当事务完成时,数据将被写入,所有客户端都应该能够看到它。希望这有助于您理解问题。考虑这个场景:(a)数据库中的值:3(b)应用程序中的事务操作(c)值显示为:0(错误数据)(d)i按下某个按钮或刷新一个页面(f)值,在应用程序中,现在更改为:3(正确数据),如果您想实时查看某些数据的更新,则需要在该数据上有一个活跃的监听器,并相应地对这些变化作出反应。事务不会改变侦听器的工作方式。谢谢,您可以分享一些有关数据库的信息吗。setPersistenceEnabled(true)
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) {
...
}
});
}
});