Firebase runTransaction无效 - MutableData为null

时间:2016-03-05 19:42:50

标签: 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) {


    }
});

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

1 个答案:

答案 0 :(得分:9)

您需要遵循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,使用现在更新的假设当前值。
  7. 如果这不能解释您所看到的行为,则可能需要检查传递给onComplete()的值。