更新(2021): There is一个新的方法调用(get在安卓上 and getData on iOS)实现您想要的行为:它首先尝试从服务器获取最新值,并且仅在无法到达服务器时才回退到缓存。使用持久侦听器的建议仍然适用,但至少有一个更清晰的选项可以一次性获取数据,即使您启用了本地缓存。
坚持是如何发挥作用的
Firebase 客户端会在内存中保留您正在监听的所有数据的副本。一旦最后一个侦听器断开连接,数据就会从内存中刷新。
如果您在 Firebase Android 应用程序中启用磁盘持久性:
Firebase.getDefaultConfig().setPersistenceEnabled(true);
Firebase 客户端将保留应用程序最近侦听的所有数据的本地副本(在磁盘上)。
当你附加一个监听器时会发生什么
假设您有以下内容ValueEventListener
:
ValueEventListener listener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
System.out.println(snapshot.getValue());
}
@Override
public void onCancelled(FirebaseError firebaseError) {
// No-op
}
};
当您添加一个ValueEventListener
到一个位置:
ref.addValueEventListener(listener);
// OR
ref.addListenerForSingleValueEvent(listener);
如果该位置的值在本地磁盘缓存中,Firebase 客户端将调用onDataChange()
立即从本地缓存中获取该值。然后还会向服务器发起检查,以请求对该值进行任何更新。它may随后调用onDataChange()
如果服务器上的数据自上次添加到缓存以来发生了更改,则再次执行此操作。
当你使用时会发生什么addListenerForSingleValueEvent
当您将单值事件侦听器添加到同一位置时:
ref.addListenerForSingleValueEvent(listener);
Firebase 客户端将(像之前的情况一样)立即调用onDataChange()
获取本地磁盘缓存中的值。它会not调用onDataChange()
即使服务器上的值不同,也可以多次。请注意,后续请求时仍会请求并返回更新的数据。
这在之前的文章中已经介绍过Firebase 同步如何使用共享数据?
解决方案和解决方法
最好的解决方案是使用addValueEventListener(),而不是单值事件侦听器。常规值侦听器将从服务器获取即时本地事件和潜在更新。
第二种解决方案是使用新的get method(于 2021 年初推出),不存在这种有问题的行为。请注意,此方法始终尝试首先从服务器获取值,因此需要更长的时间才能完全获取。如果你的值永远不会改变,那么使用可能仍然更好addListenerForSingleValueEvent
(但在这种情况下您可能不会最终到达此页面)。
作为解决方法,您还可以call keepSynced(true)在使用单值事件侦听器的位置。这确保了数据在发生变化时都会更新,从而大大提高了单值事件侦听器看到当前值的机会。