2017-06-20 33 views
0

我在Firebase上使用持久性,orderByChild()和limitToLast方法获得了奇怪的行为。Android:使用持久化与orderByChild()和limitToLast()Firebase上的错误?

这是我的基本代码。请注意,我的应用程序始终在线。 (你会发现下面的所有步骤来重现问题和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); 

获得最佳的分数:

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) { 

         } 
        }); 

这里是重现ISSU的工作流程E:

  1. 清楚你的火力数据库
  2. 显示所有的数据库,以确认一切都是空谈
  3. 显示最好的分数,以确认一切都是空谈
  4. 添加一个新的成绩:(用户1,1 )
  5. 显示最佳3分数。结果=(user1,1)=>确定
  6. 添加新的得分:(user2,2)
  7. 显示最好的3分数。结果=(用户1,1),(用户2,2)=>行

移除该应用

安装该应用再次

  • 显示最好3分数。结果=(用户1,1),(用户2,2)=>行
  • 添加2个新的分数:(用户3,3)和(USER4,4)
  • 显示最佳分数。结果=(user1,1),(user2,2)=> NOK
  • 显示所有DB =>(user1,1),(user2,2),(user3,3),(user4,4)=> OK
  • 因此,在这种特定的使用情况下,主要的问题是,“获得最佳分数”的要求,使用orderByChild和limitToLast方法,是不是增加了一些新的分数后更新。 (但它的工作步骤7!)

    我已上载的Android项目上我github上:https://github.com/MalikDE/FirebaseOrderByChildIssue

    回答

    0

    firebaser这里

    如果附加一个ChildEventListener得到分开onChildAdded为新的分数马上。

    解释行为:

    一说的火力地堡数据库使得保证的是,它不会触发数据不完整的事件。不幸的是,作为一个无模式数据库,Firebase有时不清楚数据是否完整。

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

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

    +0

    谢谢弗兰克。 只是尝试了其他的东西:当我到达第10步时,我在根节点上设置了'setValue(null)'来清除数据库。 “获得最佳3分”请求现在返回null。然后我添加一些新的分数并附加一个新的'ValueEventListener'。它返回null ...尽管事实已经被清除,但似乎Firebase仍然没有意识到它是一个完整的数据。 – MalikDe

    +0

    当您重置整个位置,火力地堡知道它有一个完整的价值(或在这种情况下,“没有值”),再次,所以它可以触发事件。然后添加单个子节点会中断该合同。基本上数据库没有办法区分你添加一个完整的孩子的情况2)添加一个孩子的一些属性。 –

    +0

    为了避免新的错误,我很想有关于该主题的技术教程:)无论如何,我找到了解决我的问题的解决方法:使用'addValueEventListener'似乎运作良好。权衡是我总是必须以实时方式使用Firebase。 – MalikDe