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