7

實現了一個具有多對多關係的Android + Firebase應用程序:用戶< - >小工具(小工具可以共享給多個用戶)。Firebase Android:使用很多聽衆的「加入」很慢,似乎與文檔相矛盾

注意事項:

  1. 列出所有用戶擁有的小工具。
  2. 用戶只能看到共享給他/她的小部件。
  3. 能夠看到共享給定Widget的所有用戶。
  4. 單個Widget可以由擁有相同權限的多個用戶擁有/管理(修改Widget並將其更改爲共享對象)。與Google雲端硬盤分享給特定用戶的方式類似。

的方法之一來實現獲取(加入式),會去與這樣的建議:https://www.firebase.com/docs/android/guide/structuring-data.html(「Joining Flattened Data」):

// fetch a list of Mary's groups 
ref.child("users/mchen/groups").addChildEventListener(new ChildEventListener() { 
    @Override 
    public void onChildAdded(DataSnapshot snapshot, String previousChildKey) { 
    // for each group, fetch the name and print it 
    String groupKey = snapshot.getKey(); 
    ref.child("groups/" + groupKey + "/name").addListenerForSingleValueEvent(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot snapshot) { 
     System.out.println("Mary is a member of this group: " + snapshot.getValue()); 
     } 
     @Override 
     public void onCancelled(FirebaseError firebaseError) { 
     // ignore 
     } 
    }); 
    } 
}); 

這個提示問題,即是否有許多潛在的聽衆會對業績產生負面影響,或許會遇到一些硬性限制。

但我們得到的文檔放心:

是真的好嗎單獨查找每個記錄?是。 Firebase協議使用Web套接字,客戶端庫對傳入和傳出的請求進行了大量的內部優化。在我們獲得數萬條記錄之前,這種方法是完全合理的。事實上,下載數據所需的時間(即字節數)使連接開銷的任何其他問題都沒有了。

但是,可以肯定的,我做了一個小測試應用程序,它比較2的方法:

  1. 附加多個ValueEventListener -s所有部件一個接一個(每火力地堡的是「結構化數據上述」指南)
  2. 附加一個單一ChildEventListener到它承載所有的部件(一個節點需要一個節點下用戶的窗口小部件的適當結構化)

在測試了4不同ent設備和android版本(4.x - 5.x)。 Firebase lib:'com.firebase:firebase-client-android:2.3.1'
在第一種方法中,表現相當令人失望。 我一直看到〜15-100個事件/秒。最低的表現,〜15次/秒經常出現,所以看起來應該認真對待。 在這種情況下,如果用戶有100個小工具,則需要大約6秒才能獲得有關所有小工具的信息(例如,滾動列表)。這太慢了。 使用1000個小工具時,通常需要40秒才能通過單獨的聽衆獲取他們的信息。太慢了。

在第二種方法中,我觀察到200-3000個事件/秒。因此比第一種方法快15-30倍!
因此看起來好像Firebase doc [...] Until we get into tens of thousands of records, this approach is perfectly reasonable [...]中的保證不是很準確,因爲它的工作速度有多慢。

鑑於這一切,我有4個相關的問題。

  1. 任何人都可以根據自己的經驗/基準來證實/反駁我的發現嗎?有關其他平臺的信息也很受歡迎,因爲有計劃在多個平臺上開發此應用程序。
  2. 什麼可能導致這種戲劇性差異的原因?內部數據結構可能?
  3. 有沒有辦法在保持第一個(多聽衆)方法的同時提高性能?
  4. 如果將多聽者方法完全棄用,以支持Firebase + Udacity教程中提供的非規格化多副本方法(「userLists」節點中的https://github.com/udacity/ShoppingListPlusPlus - 它們保留購物列表信息的每個用戶副本) ?我問另一個問題 - 這種方法的影響 - Firebase: structuring data via per-user copies? Risk of data corruption?

歡迎任何其他提示/注意事項。 TIA。

+0

由於您沒有從UI渲染中提取數據(提示:重新繪製UI很可能是您的問題),因此您的測試不相關。下載的速度幾乎肯定與正在讀取的字節數直接相關,因爲這會超出套接字活動的開銷。如果您不相信,您應該對數據進行直接的原始下載與獲取每條記錄的速度進行基準比較,將下載過程與任何數據的呈現和使用隔離。 – Kato

+1

謝謝,@Kato。 1.我做了一個沒有UI的速度測試版本,只是時機。相同的結果。 2.另一個因素是數據本地緩存('Firebase.getDefaultConfig()。setPersistenceEnabled(true)'),所以這不僅僅是帶寬。 – KarolDepka

+0

@Kato您可以評論我對這個存儲io速度相關(離線)的評論嗎? – KarolDepka

回答

0

"This prompts the question whether having potentially many listeners will have a negative impact on performance or perhaps would hit some hard limit."

答案是Firebase Realtime database一樣,因爲它是新Cloud Firestore database

我不在乎你有多少連接或你有多少個監聽器,它關係你在客戶端處理多少數據。

所以,如果你有100個聽衆,聽100位的小數據,這是一個相當便宜,但如果每個聽衆正在監聽一個不斷變化的數據流,這對客戶來說變得非常昂貴處理它很快。

而且由於移動設備差異很大,很難知道有多少是太多了。因此,如果您針對的是傾向於擁有非常高端手機的美國用戶,那麼如果我們將手機定位在功能低得多的國家/地區,這將是一個不同的限制。

所以,你可以有很多的聽衆,只要你想,如果你刪除相應的他們活動的生命週期,如exaplined here

還有另一種方法,使用addListenerForSingleValueEvent。在這種情況下,不需要刪除監聽器。