【问题标题】:Android Firebase database transactionAndroid Firebase 数据库事务
【发布时间】:2018-10-13 07:59:22
【问题描述】:
  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。 之后,它会根据数据库值正确更新。

我无法弄清楚每次第一次运行应用程序/代码时 data.token = 0 的值的原因。

【问题讨论】:

    标签: android firebase firebase-realtime-database


    【解决方案1】:

    您应该期望事务中可用数据的初始快照在其首次执行期间可能为空。请注意the documentation

    注意:因为doTransaction()被多次调用,所以必须是 能够处理空数据。即使您的数据中存在现有数据 远程数据库,事务时可能没有本地缓存 函数运行,导致初始值为 null。

    还在javadoc 中写道:

    这个方法将被调用,可能多次,当前 此位置的数据。

    预计您的处理程序第一次运行时,它将处理一个空数据库。然后,当那里的数据已知(如果有)时,您也应该准备好处理这种情况。如果您不想在该位置没有数据(或未知数据)的情况下执行任何操作,只需返回一个成功的 Transaction 而不更改 mutableData。

    【讨论】:

    • 这行得通。但是数据并没有实时反映。当从数据库中检索数据时,最初它显示为 0。在与 UI 元素进行某些交互(如按下按钮或恢复)后,“0”会更改为数据库中的实际值。而且这种情况不仅发生在第一次访问数据库时,而且每次要检索数据时都会发生。如何避免这种情况?第一次自己如何显示实际数据?
    • 我不确定你的意思。事务完成后,数据将被写入,所有客户端都应该能够看到它。
    • 希望这可以帮助您理解问题。考虑这种情况:(A)数据库中的值:3(B)事务操作(C)应用程序中的值显示为:0(错误数据)(D)我按下了某个按钮或有点刷新了应用程序中的页面(F)值更改为:3(正确数据)
    • 如果您想实时查看某些数据的更新,您需要一个对该数据的活动侦听器,并相应地对这些更改做出反应。事务不会改变监听器的工作方式。
    【解决方案2】:

    感谢您的解释,@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) {
            ...
          }
    
        });
      }
    });
    

    【讨论】:

    • 谢谢,您能否分享一些关于 database.setPersistenceEnabled(true) 的信息
    猜你喜欢
    • 2021-11-23
    • 2011-12-30
    • 1970-01-01
    • 2018-10-17
    • 2019-05-15
    • 2020-09-19
    • 2019-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多