2017-06-20 64 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