Firebase 离线功能和 addListenerForSingleValueEvent [英] Firebase Offline Capabilities and addListenerForSingleValueEvent

查看:39
本文介绍了Firebase 离线功能和 addListenerForSingleValueEvent的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每当我将 addListenerForSingleValueEventsetPersistenceEnabled(true) 一起使用时,我只能设法获得 DataSnapshot 的本地离线副本,没有 从服务器更新的 DataSnapshot.

但是,如果我使用 addValueEventListenersetPersistenceEnabled(true),我可以从服务器获取 DataSnapshot 的最新副本.>

这对于 addListenerForSingleValueEvent 是否正常,因为它仅在本地(离线)搜索 DataSnapshot 并在成功检索 DataSnapshot 后删除其侦听器 ONCE(离线还是在线)?

解决方案

更新 (2021):有一个新的方法调用(get 在 Android 上getData 在 iOS 上) 实现您想要的行为:它首先尝试从服务器获取最新值,并且仅在可以时回退到缓存中t 到达服务器.使用持久侦听器的建议仍然适用,但即使您启用了本地缓存,至少也有一个更清晰的选择来获取数据一次.


持久性的工作原理

Firebase 客户端会在内存中保留一份您正在积极侦听的所有数据的副本.一旦最后一个监听器断开连接,数据就会从内存中刷新.

如果您在 Firebase Android 应用程序中启用磁盘持久性:

Firebase.getDefaultConfig().setPersistenceEnabled(true);

Firebase 客户端将保留该应用最近侦听的所有数据的本地副本(在磁盘上).

附加监听器时会发生什么

假设您有以下 ValueEventListener:

ValueEventListener listener = new ValueEventListener() {@覆盖公共无效 onDataChange(数据快照快照){System.out.println(snapshot.getValue());}@覆盖public void onCancelled(FirebaseError firebaseError) {//无操作}};

当您将 ValueEventListener 添加到某个位置时:

ref.addValueEventListener(listener);//或者ref.addListenerForSingleValueEvent(listener);

如果该位置的值在本地磁盘缓存中,Firebase 客户端将立即从本地缓存中为该值调用 onDataChange().If 还将启动与服务器的检查,以要求对该值进行任何更新.如果自上次添加到缓存后服务器上的数据发生更改,它可能随后再次调用 onDataChange().

当你使用 addListenerForSingleValueEvent

时会发生什么

当您将单值事件侦听器添加到同一位置时:

ref.addListenerForSingleValueEvent(listener);

Firebase 客户端将(与前一种情况一样)立即调用 onDataChange() 获取本地磁盘缓存中的值.它不再调用onDataChange(),即使服务器上的值不同.请注意,更新的数据仍然会在后续请求中被请求和返回.

这在之前的 Firebase 同步如何工作,共享数据?

解决方案和解决方法

最好的解决方案是使用 addValueEventListener(),而不是单值事件侦听器.常规值侦听器将从服务器获取即时本地事件和潜在更新.

第二种解决方案是使用新的 get 方法(于 2021 年初引入),它没有这种有问题的行为.请注意,此方法总是尝试首先从服务器获取值,因此需要更长的时间才能完全获取.如果您的值从未改变,使用 addListenerForSingleValueEvent 可能仍然更好(但在这种情况下您可能不会出现在此页面上).

作为一种解决方法,您还可以在您使用单值事件侦听器的位置调用 keepSynced(true).这可确保数据在发生变化时及时更新,从而极大地提高了单值事件侦听器看到当前值的机会.

Whenever I use addListenerForSingleValueEvent with setPersistenceEnabled(true), I only manage to get a local offline copy of DataSnapshot and NOT the updated DataSnapshot from the server.

However, if I use addValueEventListener with setPersistenceEnabled(true), I can get the latest copy of DataSnapshot from the server.

Is this normal for addListenerForSingleValueEvent as it only searches DataSnapshot locally (offline) and removes its listener after successfully retrieving DataSnapshot ONCE (either offline or online)?

解决方案

Update (2021): There is a new method call (get on Android and getData on iOS) that implement the behavior you'll like want: it first tries to get the latest value from the server, and only falls back to the cache when it can't reach the server. The recommendation to use persistent listeners still applies, but at least there's a cleaner option for getting data once even when you have local caching enabled.


How persistence works

The Firebase client keeps a copy of all data you're actively listening to in memory. Once the last listener disconnects, the data is flushed from memory.

If you enable disk persistence in a Firebase Android application with:

Firebase.getDefaultConfig().setPersistenceEnabled(true); 

The Firebase client will keep a local copy (on disk) of all data that the app has recently listened to.

What happens when you attach a listener

Say you have the following ValueEventListener:

ValueEventListener listener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot snapshot) {
        System.out.println(snapshot.getValue());
    }

    @Override
    public void onCancelled(FirebaseError firebaseError) {
        // No-op
    }
};

When you add a ValueEventListener to a location:

ref.addValueEventListener(listener); 
// OR
ref.addListenerForSingleValueEvent(listener); 

If the value of the location is in the local disk cache, the Firebase client will invoke onDataChange() immediately for that value from the local cache. If will then also initiate a check with the server, to ask for any updates to the value. It may subsequently invoke onDataChange() again if there has been a change of the data on the server since it was last added to the cache.

What happens when you use addListenerForSingleValueEvent

When you add a single value event listener to the same location:

ref.addListenerForSingleValueEvent(listener);

The Firebase client will (like in the previous situation) immediately invoke onDataChange() for the value from the local disk cache. It will not invoke the onDataChange() any more times, even if the value on the server turns out to be different. Do note that updated data still will be requested and returned on subsequent requests.

This was covered previously in How does Firebase sync work, with shared data?

Solution and workaround

The best solution is to use addValueEventListener(), instead of a single-value event listener. A regular value listener will get both the immediate local event and the potential update from the server.

A second solution is to use the new get method (introduced in early 2021), which doesn't have this problematic behavior. Note that this method always tries to first fetch the value from the server, so it will take longer to completely. If your value never changes, it might still be better to use addListenerForSingleValueEvent (but you probably wouldn't have ended up on this page in that case).

As a workaround you can also call keepSynced(true) on the locations where you use a single-value event listener. This ensures that the data is updated whenever it changes, which drastically improves the chance that your single-value event listener will see the current value.

这篇关于Firebase 离线功能和 addListenerForSingleValueEvent的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆