android - Firebase runTransaction 不工作 - MutableData 为空

标签 android firebase firebase-realtime-database transactions

我正在尝试使用 Firebase 数据库的 runTransaction() 但它不起作用。这是我正在使用的代码。

numQuestionRef.runTransaction(new Transaction.Handler() {
    @Override
    public Transaction.Result doTransaction(MutableData mutableData) {
        String numQuestions = (String) mutableData.getValue();
        long value = Long.parseLong(numQuestions, 16);
        value++;
        String incHex = Long.toHexString(value);
        mutableData.setValue(incHex);
        return Transaction.success(mutableData);
    }

    @Override
    public void onComplete(FirebaseError firebaseError, boolean b, DataSnapshot dataSnapshot) {


    }
});

当我在我的应用程序中按下一个按钮时,这个代码被激活。当我启动应用程序后第一次按下按钮时,我的数据库没有改变。但是当我在启动应用程序后第二次按下按钮时,它会将其更新为下一个数字。我不明白它出了什么问题,或者为什么它只在第二次按下按钮时才出现。

最佳答案

您需要遵循 Firebase documentation for handling transactions 中使用的模式并处理您的交易回调没有当前值的情况:

public Transaction.Result doTransaction(MutableData currentData) {
    long value = 0;
    if(currentData.getValue() != null) {
        String numQuestions = (String) currentData.getValue();
        value = Long.parseLong(numQuestions, 16);
    }
    value++;
    String incHex = Long.toHexString(value);
    currentData.setValue(incHex);
    return Transaction.success(currentData);
}

您需要这样做的原因是 Firebase 可能(并且经常会)多次执行您的事务回调,您需要满足这一点。

  1. 当您第一次调用 runTransaction() 时,Firebase 客户端将立即调用您的 doTransaction() 回调,并使用其对当前数据的当前猜测。这通常是 null
  2. 您的代码根据当前值返回下一个值。在上面的例子中,如果当前值为 null,则新值将为 1
  3. 然后 Firebase 客户端将假定的当前值和新值发送到服务器。
  4. 如果实际存储的值与假定的当前值相同,Firebase 服务器将写入您指定的新值。
  5. 如果实际存储的值与假定的当前值不同,Firebase 服务器将拒绝新值并将实际当前值发送给客户端。
  6. 在此阶段,客户返回到第 1 步,并使用现已更新的假定当前值。

如果这不能解释您所看到的行为,您可能需要检查传递给 onComplete() 的值。

关于android - Firebase runTransaction 不工作 - MutableData 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35818946/

相关文章:

android - Firebase Analytics,无法查看事件中传递的值

angular - 没有 AngularFireDatabase、AngularFireAuth 的提供者

android - 如何使用 Intent 将 ArrayList<File> 对象从一个 Activity 传递到另一个 Activity?

android - Crashlytics.log (""在哪里);去?

android - 如何在整个recyclerview行上单击以选中复选框

javascript - Firebase 数据库触发器 - 如何等待调用

swift - Xcode 无法识别 FUITableViewDataSource

android - 如何使用 Firebase 列表适配器

Android 开放 Intent ://protocol in WebView

android - com.google.firebase.messaging.zza : can't find referenced class android. graphics.drawable.AdaptiveIconDrawable