7

我在火力基地很新,我正试图绕过它。我有这个适配器,ValueEventListener每次创建它时都会注册到。如果我不分离它,当我旋转手机并且适配器在片段中被破坏/重建时,听众会加起来吗?还是 firebase 足够聪明,可以知道这个特定的侦听器已经存在?

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

4

1 回答 1

12

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

  1. 你在哪里连接你的听众?如果您将它附加到除 之外的任何位置onResume,它将重新初始化您的侦听器。设置侦听器时,它会触发该特定节点的所有事件。但是,我仍然在我的 Firebase 参考中进行所有注册和注销onPause,并且onResume

  2. 您可以拥有任何 Firebase 侦听器的多个实例。

    firebase 是否足够聪明,可以知道这个特定的侦听器已经存在?

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

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

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

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

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

    • 首先 - 保存到缓存。

    • 第二次触发回调。

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


回答问题

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

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

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

  • 然后,onPause我将把这些数据添加到我ignoredList的监听器中并清空childEvent监听器。

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

  • onAdded事件侦听器中,我根据我的列表检查新添加的对象。如果我有它,我会将它从列表中删除,仅此而已。基本上无视它。如果对象不在我的范围内,ignoredList我会像往常一样处理它。onAdded如果我从除, (即onRemoved onChanged或)之外的回调之一接收到它,onMoved那么我将对列表中的该对象进行该事件更改并从ignoredList.

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

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

于 2015-04-16T21:29:03.407 回答