Firebase Android:使用许多侦听器缓慢“加入”,似乎与文档

时间:2016-03-14 19:57:12

标签: android join firebase database-performance firebase-realtime-database

实施具有多对多关系的Android + Firebase应用:用户< - >窗口小部件(窗口小部件可以与多个用户共享)。

考虑:

  1. 列出用户拥有的所有小部件。
  2. 用户只能看到与他/她共享的小部件。
  3. 能够看到共享给定Widget的所有用户。
  4. 单个Widget可以由具有相同权限的多个用户拥有/管理(修改Widget并更改共享对象)。与Google云端硬盘与特定用户共享的方式类似。
  5. 实现抓取(join-style)的方法之一就是采用这个建议: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套接字,客户端库对传入和传出请求进行大量内部优化。在我们进入成千上万条记录之前,这种方法非常合理。实际上,下载数据所需的时间(即字节数)会使关于连接开销的任何其他问题黯然失色。

    但是,可以肯定的是,我做了一个小测试应用程序来比较两种方法:

    1. 逐个将多个ValueEventListener - s附加到所有小部件(根据Firebase的“结构化数据”指南)
    2. 将单个ChildEventListener附加到托管所有窗口小部件的节点(需要在一个节点下充分构建用户窗口小部件)
    3. 测试了4种不同的设备和Android版本(4.x - 5.x)。 Firebase lib:'com.firebase:firebase-client-android:2.3.1'
      在第一种方法中,表现相当令人失望。 我一直看到~15-100个事件/秒。最低的性能,大约15个事件/ s经常出现,所以看起来应该认真对待。 在这种情况下,如果用户有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?中询问这种方法的含义。
      5. 欢迎任何其他提示/考虑因素。 TIA。

1 个答案:

答案 0 :(得分: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比特的小数据,这已经变得非常便宜但如果每个听众都在收听不断变化的数据流,那对于客户来说这已经变得非常昂贵快速处理。

而且由于移动设备差异很大,很难知道有多少是太多。因此,如果您针对的是那些倾向于拥有非常高端手机的美国用户,那么如果我们定位的是手机功率低得多的国家/地区,这将是一个不同的限制。

因此,如果您根据活动的生命周期删除它们,您可以拥有任意数量的侦听器,如同here所示。

使用addListenerForSingleValueEvent还有另一种方法。在这种情况下,不需要删除监听器。