【问题标题】:Android : Bug on Firebase using persistence with orderByChild() and limitToLast()?Android:使用 orderByChild() 和 limitToLast() 持久性在 Firebase 上的错误?
【发布时间】:2017-06-20 15:04:25
【问题描述】:

我在 Firebase 上使用持久性、orderByChild() 和 limitToLast 方法遇到了一个奇怪的行为。

这是我的基本代码。请注意,我的应用程序始终在线。 (您将在下面找到重现问题的所有步骤以及示例项目的 github 链接)

在我的应用程序类中启用持久性:

FirebaseDatabase.getInstance().setPersistenceEnabled(true);

给用户加分:

FirebaseDatabase.getInstance().getReference("scores")
.child("users")
.child("user1") //add a new user
.child("score") //along with a new score
.setValue(1);

获得最好的 3 分:

FirebaseDatabase.getInstance().getReference("scores")
.child("users")
.orderByChild("score")
.limitToLast(3)
.addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                        }

                        @Override
                        public void onCancelled(DatabaseError databaseError) {

                        }
                    });

这是重现问题的工作流程:

  1. 清除您的 Firebase 数据库
  2. 显示所有 DB 以确认一切为空
  3. 显示最好的 3 个分数以确认一切都是空的
  4. 添加新分数:(user1, 1)
  5. 显示最好的 3 个分数。结果 = (user1, 1) => 好的
  6. 添加新分数:(user2, 2)
  7. 显示最好的 3 个分数。结果 = (user1, 1), (user2, 2) => OK

删除应用

再次安装应用

  1. 显示最好的 3 个分数。结果 = (user1, 1), (user2, 2) => OK
  2. 添加 2 个新分数:(user3, 3) 和 (user4, 4)
  3. 显示最好的 3 个分数。结果 = (user1, 1), (user2, 2) => NOK
  4. 显示所有 DB => (user1, 1), (user2, 2), (user3, 3), (user4, 4) => OK

所以在这个特定用例中,主要问题是使用 orderByChild 和 limitToLast 方法的“获得最佳 3 分”请求在添加一些新分数后不会更新。 (但它在第 7 步有效!)

我已经在我的 github 上上传了 Android 项目:https://github.com/MalikDE/FirebaseOrderByChildIssue

【问题讨论】:

    标签: android firebase firebase-realtime-database persistence


    【解决方案1】:

    firebaser 在这里

    如果您附上ChildEventListener,您立即获得一个单独的onChildAdded 以获得新的分数。

    行为说明:

    Firebase 数据库做出的一项保证是它永远不会触发包含不完整数据的事件。不幸的是,作为一个无模式数据库,Firebase 有时并不清楚数据是否完整。

    当您使用 ValueEventListener 时,Firebase 只有在知道该位置的完整数据后才会触发该事件。由于它没有意识到新分数是一个全新的孩子,因此它不会触发具有该附加分数的事件。

    我们希望更好地检测到这一点,但在不破坏向后兼容性的情况下,我们不太可能在当前 API 中做到这一点。

    【讨论】:

    • 谢谢弗兰克。只是尝试了其他方法:当我到达第 10 步时,我在根节点上setValue(null),以清除数据库。 “获得最佳 3 分”请求现在返回 null。然后我添加一些新分数并附加一个新的ValueEventListener。它返回 null ...尽管所有内容都已清除,但 Firebase 似乎仍然没有意识到这是一个完整的数据。
    • 当您重置整个位置时,Firebase 再次知道它有一个完整的值(或者在本例中为“缺少值”),因此它可以触发该事件。然后添加单个子节点会破坏该合同。本质上,数据库无法区分以下情况:1)添加一个完整的孩子 2)添加孩子的一些属性。
    • 为了避免新的错误,我很想有一个关于该主题的技术教程:) 无论如何,我找到了解决我的问题的方法:使用addValueEventListener 似乎效果很好。权衡是我总是必须实时使用 Firebase。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-19
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 2017-03-27
    • 2018-01-26
    • 1970-01-01
    相关资源
    最近更新 更多