我在firebase上很新,我正试图绕过它。
我有这个适配器,每次创建时都会注册到ValueEventListener
。如果我不拆卸它,听众会在我旋转手机时加起来并且适配器在片段中被破坏/重建吗?或者firebase足够聪明,知道这个特定的监听器已经存在了吗?
PS :我尝试使用它在片段的onPause
方法中取消注册此侦听器,但是firebase似乎正在删除我的缓存,所以在片段旋转之后需要一段时间再次获取数据,之前没有发生过。
答案 0 :(得分:12)
好问题。所以,很少有事情需要注意:
你在哪里附加你的听众?如果你将它附加在但 onResume
的任何地方,它将重新初始化你的听众。设置侦听器时,它会触发该特定节点的所有事件。但是,我仍然会在onPause
和onResume
您可以拥有任何Firebase侦听器的多个实例。
firebase足够聪明,知道这个特定的监听器已经存在吗?
Firebase 意识到侦听器已经存在,并且不会发送两次相同的事件。但是,在旋转时,您正在创建一个新的侦听器实例。 Firebase无法将此视为同一个实例化侦听器。因此,您再次收到所有数据。
Firebase缓存所有数据。附加片段并设置侦听器后,firebase将进行两次主要调用 -
首先 - 检索缓存数据的查询。
第二 - 对远程数据的查询。
首先调用缓存很好,因为它仍适用于网络速度很慢的情况。 现在,请耐心等待...... 当Firebase从在线服务器接收到该快照时,它将对远程对象和本地对象进行复杂的评估。 Firebase将尽最大努力使用复杂的ID合并对象,这些ID利用时间戳和黑魔法[需要来源]。使用此新快照,如果需要,它会将其保存到服务器。然后,** Firebase将仅在与缓存版本不同且相对于提供所述数据的侦听器实例的更改时向您提供日期。此缓存驱动的结构甚至适用于您保存您的数据:
首先保存到缓存。
第二次触发回调。
第三次尝试保存到服务器。
如果您将收听者与Firebase onPause
/ onResume
相关联,您将再次收到所有数据。不再接收它的唯一方法是维护该侦听器的相同实例。
除了维护我的侦听器实例外,我还使用了另一种解决方案。在我看来,我不喜欢它。但仍然是我经常使用的。我做的是
我会保留一个名为final List<String>
的{{1}}。此列表将由ignoredList
密钥构建,该密钥将是适配器中已有对象的密钥。
然后,在String
中,我会将此数据添加到onPause
并将ignoredList
侦听器归零。
在childEvent
回调之后,我设置了onResume
侦听器的新实例。
在事件监听器的childEvent
上,我根据列表检查新添加的对象。如果我拥有它,我将从列表中删除它,没有别的。基本上忽略它。如果对象不在我的onAdded
中,我将像平常一样处理它。如果我是从ignoredList
以外的其中一个回复(即onAdded
onRemoved
或onChanged
)收到的,那么我会将该事件更改为列表中的该对象并从onMoved
中删除。
现在,我承认这不是最漂亮的解决方案。如果两个源正在修改相同的DataSnapshot,您可能看到不正确的数据。这将是一个很小的机会,但完全有可能。幸运的是,如果数据集不准确,则无法保存到Firebase。
我一直在积极寻找更好的策略,如果我找到一个我会分享。与此同时,这个解决方案已经完美地适用于我的应用程序。