Android Firebase数据库事务

Android Firebase数据库事务,android,firebase,firebase-realtime-database,Android,Firebase,Firebase Realtime Database,每当代码第一次运行时,data.tokenNo的值为0。 之后,它将根据数据库值正确更新 我无法理解是什么使data.token的值在每次应用程序/代码的第一次运行时都为0。您应该期望事务中可用数据的初始快照在第一次执行时可能为空。请注意: 注意:由于doTransaction()被多次调用,因此必须 能够处理空数据。即使您的数据库中存在现有数据 远程数据库,当事务发生时,它可能不会在本地缓存 函数运行,导致初始值为null 此外,报告还说: 此方法将使用当前 此位置的数据 第一次运行处理程序时

每当代码第一次运行时,data.tokenNo的值为0。 之后,它将根据数据库值正确更新


我无法理解是什么使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) {
        ...
      }

    });
  }
});