Firebase 在 Android 中的适配器中添加侦听器

Firebase adding listeners in adapters in Android

我是 firebase 的新手,我正在努力了解它。 我有这个适配器,每次创建时都会注册到 ValueEventListener。如果我不分离它,当我旋转我的 phone 并且适配器在片段中获得 destroyed/rebuilt 时,听众会加起来吗?或者 firebase 是否足够聪明,知道这个特定的侦听器已经存在?

PS:我试图在使用它的片段的 onPause 方法中注销此侦听器,但 firebase 似乎正在删除我的缓存所以片段旋转后需要一段时间才能再次获取数据,这在以前没有发生过。

好问题。所以,有几点需要注意:

  1. 你在哪里附加你的监听器?如果你在任何地方附加这个但是 onResume ,它将重新初始化您的侦听器。设置侦听器时,它会触发该特定节点的所有事件。但是,我仍然在 onPauseonResume

  2. 中对我的 Firebase 引用进行所有注册和注销
  3. 您可以拥有任何 Firebase 侦听器的多个实例

    Is firebase smart enough to know that this particular listener already exists?

    Firebase 知道侦听器已经存在并且不会发送相同的事件两次。但是,旋转时您正在创建侦听器的新实例。 Firebase 无法将其视为同一个实例化侦听器。因此,您会再次收到所有数据。

  4. Firebase 缓存所有数据。附加片段并设置侦听器后,firebase 将进行两次主要调用 -

    • 首先 - 检索缓存数据的查询。

    • 其二 - 对远程数据的查询。

    首先调用缓存很好,因为它在网络缓慢或没有网络的情况下仍然有效。 现在,请耐心等待... 当 Firebase 从在线服务器接收到该快照时,它将对远程对象和本地对象进行复杂的评估。尽其所能,Firebase 将使用利用时间戳和黑魔法的复杂 ID 合并对象 [来源需要]。有了这个新快照,如果需要,它会将其保存到服务器。然后,**Firebase 仅当它与缓存版本不同并且 相对于提供所述数据的侦听器实例发生变化时才会向您提供日期。 这种缓存驱动的结构甚至适用保存数据时:

    • 首先- 保存到缓存。

    • 二次触发回调。

    • 第三次尝试保存到服务器。


回答问题

如果您将侦听器附加到 Firebase onPause/onResume,您将再次收到所有数据。不再接收它的唯一方法是维护该侦听器的相同实例。

除了维护我的侦听器实例,我还使用了另一种解决方案。在我看来,我不喜欢它。但仍然是我最常使用的。我所做的是

  • 我会养一个final List<String>,叫ignoredList。该列表将由 String 键构建,这将是您适配器中已有对象的键。

  • 然后,在 onPause 中,我会将此数据添加到我的 ignoredList 中,并清空 childEvent 侦听器。

  • onResume 回调之后,我设置了一个新的 childEvent 侦听器实例。

  • 在事件侦听器的 onAdded 上,我根据列表检查新添加的对象。如果我有它,我会把它从列表中删除,除此之外别无其他。基本上忽略它。如果该对象不在我的 ignoredList 中,我会像往常一样处理它。如果我从 onAdded 以外的回调之一收到它(即 onRemoved onChangedonMoved),那么我会将事件更改为列表中的那个对象并从 ignoredList 中删除。

现在,我承认这并不是最好的解决方案。如果两个源正在修改同一个 DataSnapshot,您可能 看到不正确的数据。这将是一个很小的机会,但完全有可能。幸运的是,如果数据集不准确,它不会保存到 Firebase。

我一直在为此积极寻找更好的策略,如果我找到了,我会分享。与此同时,这个解决方案一直在为我的应用程序完美运行。