Android:使用 orderByChild() 和 limitToLast() 的持久性在 Firebase 上存在错误?
Android : Bug on Firebase using persistence with orderByChild() and limitToLast()?
我在使用持久性、orderByChild() 和 limitToLast 方法的 Firebase 上有一个奇怪的行为。
这是我的基本代码。请注意,我的应用程序始终在线。 (您将在下面找到重现问题的所有步骤以及示例项目的 github link)
在我的应用程序中启用持久性 class:
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) {
}
});
这是重现问题的工作流程:
- 清空你的 firebase 数据库
- 显示所有数据库以确认一切为空
- 显示最好的3个分数以确认一切为空
- 添加新分数:(user1, 1)
- 显示最好的3个分数。结果 = (user1, 1) => OK
- 添加新分数:(user2, 2)
- 显示最好的3个分数。结果 = (user1, 1), (user2, 2) => OK
删除应用程序
重新安装应用程序
- 显示最好的3个分数。结果 = (user1, 1), (user2, 2) => OK
- 添加 2 个新分数:(user3, 3) 和 (user4, 4)
- 显示最好的3个分数。结果 = (user1, 1), (user2, 2) => NOK
- 显示所有数据库 => (user1, 1), (user2, 2), (user3, 3), (user4, 4) => OK
所以在这个特定的用例中,主要问题是使用 orderByChild 和 limitToLast 方法的 "get the best 3 scores" 请求在添加一些新分数后没有更新。
(但它在第 7 步中有效!)
我已经在我的 github 上上传了 Android 项目:https://github.com/MalikDE/FirebaseOrderByChildIssue
firebaser 在这里
如果您附上 ChildEventListener
,您 将 立即获得单独的 onChildAdded
新乐谱。
行为解释:
Firebase 数据库做出的保证之一是它永远不会触发数据不完整的事件。不幸的是,作为一个无模式数据库,Firebase 有时并不清楚数据是否完整。
当您使用 ValueEventListener
时,Firebase 只有在知道该位置的完整数据后才会触发事件。由于它没有意识到新分数是一个全新的 child,因此它不会触发具有该添加分数的事件。
我们很乐意更好地检测到这一点,但我们不太可能在当前 API 内做到这一点而不破坏向后兼容性。
我在使用持久性、orderByChild() 和 limitToLast 方法的 Firebase 上有一个奇怪的行为。
这是我的基本代码。请注意,我的应用程序始终在线。 (您将在下面找到重现问题的所有步骤以及示例项目的 github link)
在我的应用程序中启用持久性 class:
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) {
}
});
这是重现问题的工作流程:
- 清空你的 firebase 数据库
- 显示所有数据库以确认一切为空
- 显示最好的3个分数以确认一切为空
- 添加新分数:(user1, 1)
- 显示最好的3个分数。结果 = (user1, 1) => OK
- 添加新分数:(user2, 2)
- 显示最好的3个分数。结果 = (user1, 1), (user2, 2) => OK
删除应用程序
重新安装应用程序
- 显示最好的3个分数。结果 = (user1, 1), (user2, 2) => OK
- 添加 2 个新分数:(user3, 3) 和 (user4, 4)
- 显示最好的3个分数。结果 = (user1, 1), (user2, 2) => NOK
- 显示所有数据库 => (user1, 1), (user2, 2), (user3, 3), (user4, 4) => OK
所以在这个特定的用例中,主要问题是使用 orderByChild 和 limitToLast 方法的 "get the best 3 scores" 请求在添加一些新分数后没有更新。 (但它在第 7 步中有效!)
我已经在我的 github 上上传了 Android 项目:https://github.com/MalikDE/FirebaseOrderByChildIssue
firebaser 在这里
如果您附上 ChildEventListener
,您 将 立即获得单独的 onChildAdded
新乐谱。
行为解释:
Firebase 数据库做出的保证之一是它永远不会触发数据不完整的事件。不幸的是,作为一个无模式数据库,Firebase 有时并不清楚数据是否完整。
当您使用 ValueEventListener
时,Firebase 只有在知道该位置的完整数据后才会触发事件。由于它没有意识到新分数是一个全新的 child,因此它不会触发具有该添加分数的事件。
我们很乐意更好地检测到这一点,但我们不太可能在当前 API 内做到这一点而不破坏向后兼容性。