Firebase runTransaction 不工作 - MutableData 为空

Firebase runTransaction not working - MutableData is null

我正在尝试使用 runTransaction() 的 Firebase 数据库,但它无法正常工作。这是我正在使用的代码。

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. 您的代码 returns 基于当前值的下一个值。在上述情况下,如果当前值为 null,则新值将为 1.
  3. 然后 Firebase 客户端将假定的当前值和新值发送到服务器。
  4. 如果实际存储的值与假定的当前值相同,Firebase 服务器将写入您指定的新值。
  5. 如果实际存储的值与假定的当前值不同,Firebase 服务器拒绝新值并将实际当前值发送给客户端。
  6. 在此阶段,客户端返回到步骤 1,并使用现在更新的假定当前值。

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