如果先前在本地提交,Firebase 事务不会远程中止

Firebase transaction doesn't abort remotely if previously committed locally

我正在构建一个 Android 应用程序,多个用户可以在其中访问、修改和删除同一项目,并且我正在使用 Firebase 同步所有设备。 为了跟踪更新,该项目有一个时间戳。 我写了一个事务,这样当我尝试删除项目时,它会检查我的副本的时间戳是否早于远程副本:在这种情况下,事务中止并且项目不会被删除。

这是我的问题:

  1. 我的设备离线
  2. 我删除成功了
  3. 另一个用户修改了远程数据库上的项目
  4. 我的设备上线并传播他的删除

我认为它会远程中止,因为远程时间戳较新。 如果我只能根据我的本地数据中止决策,我真的看不出中止函数的意义...

我应该如何处理 Firebase 中的此类冲突?

-- 更新

这是我用来删除项目的代码。如果在本地删除后另一个用户远程更改了项目,它应该中止。

private void removeItem(final ListItem item, final Firebase itemRef) {
    itemRef.runTransaction(new Transaction.Handler() {
        @Override
        public Transaction.Result doTransaction(MutableData mutableData) {
            if(mutableData == null) return Transaction.abort();
            else if((long)mutableData.child("lastUpdate").getValue() > item.getLastUpdate()) return Transaction.abort();
            else{
                itemRef.removeValue();
                return Transaction.success(mutableData);
            }
        }
    });

请注意我使用 itemRef.removeValue() 而不是 mutableData.setValue(null) 因为第二个似乎不起作用。

Firebase 最初在客户端应用事务,以提高并发性。如果该决定不符合您的用例,您可以将附加参数传递给 transaction 方法,告诉它绕过本地应用。

https://www.firebase.com/docs/web/api/firebase/transaction.html

applyLocally Boolean Optional

By default, events are raised each time the transaction update function runs. So if it is run multiple times, you may see intermediate states. You can set this to false to suppress these intermediate states and instead wait until the transaction has completed before events are raised.

我是这样解决问题的:

  1. 我用的是mutableData.setValue(null),不然Firebase无法让事务正常工作
  2. 我将 applyLocally 布尔值明确设置为 true,因为我也需要查看本地事件

我不明白为什么 mutableData.setValue(null) 以前没有工作,我可能遗漏了一些以前的错误,但这就是问题所在。