数据库错误:事务被后续设置如何解决覆盖

时间:2016-12-10 17:26:56

标签: android firebase firebase-realtime-database

我知道这是一个常见错误,SO中有很多线程。但没有任何帮助我。

这是我的问题:

我的数据库结构:     根         /职位/         /用户帖子/用户ID /

每篇文章都有一些属性,包括:     likeCount     喜欢> id:true

每当创建帖子时,它都存储在/ posts /和/ user-posts / node中。但是当我喜欢这个帖子时,它会更新为一个,而另一个则会因为问题标题中提到的错误而失败。

用于在firebase DB中插入帖子的代码:

Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put("/posts/" + key, feedValues);
childUpdates.put("/user-posts/" + userId + "/" + key, feedValues);
dbRef.updateChildren(childUpdates);

代码用于:

public static void updateLikeInServer(DatabaseReference dbRef, final String userId) {
    Log.d(TAG, "updateLikeInServer:started:");
    dbRef.runTransaction(new Transaction.Handler() {
        @Override
        public Transaction.Result doTransaction(MutableData mutableData) {
            Post post = mutableData.getValue(Post.class);
            if (post == null) {  // It comes as null for /user-posts/ but not for /posts/
                return Transaction.success(mutableData);
            }

            if (post.getLikes().containsKey(userId)) {
                post.setLikesCount(post.getLikesCount() - 1);
                post.getLikes().remove(userId);
            } else {
                post.setLikesCount(post.getLikesCount() + 1);
                post.getLikes().put(userId, true);
            }

            // Set value and report transaction success
            mutableData.setValue(post);
            return Transaction.success(mutableData);
        }

        @Override
        public void onComplete(DatabaseError databaseError, boolean b,
                               DataSnapshot dataSnapshot) {
            // Transaction completed
            Log.d(TAG, "updateLikeInServer:onComplete: " + databaseError);
        }
    });
}

由于需要在/ user-posts /和/ posts /中更新类似的计数,我使用相应的DatabaseReference调用上述方法两次。

参数

  1. 如果失败,则node / user-posts /和/ posts /都会失败。为什么两个地方都没有失败?
  2. 它只会在第一次失败,但是如果你连续这样做就像&gt;不喜欢&gt;喜欢&gt;不喜欢,它从第二次在病房成功两个位置。为什么会这样?
  3. 最重要:只有当我喜欢朋友创建的帖子时才会出现错误。如果我喜欢自己的帖子,没有错误。

1 个答案:

答案 0 :(得分:-1)

解决了以下解决方法的问题。不知道这是否是正确的方式,但是如果有更好的解决方案,我很乐意向别人了解。

因为它只发生在第一次事务中,所以我试图检查错误并再次重试相同的操作,这在第二次尝试中成功。

@Override
        public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
            // Transaction completed
            Log.d(TAG, "updateLikeInServer:onComplete: " + databaseError);
            if (databaseError != null && databaseError.getCode() == DatabaseError.OVERRIDDEN_BY_SET) {
                // Retry the same
                updateLikeInServer(dbRef, userId);
            }
        } 

上面的代码解决了我的问题。但如果可能的话,我很乐意倾听最佳答案。