【问题标题】:Firebase onDataChange not called when offline离线时未调用 Firebase onDataChange
【发布时间】:2017-02-24 04:50:13
【问题描述】:

关于 Firebase ValueEventListener,我遇到了一个非常奇怪的情况。

当手机连接到互联网时,它可以正常工作。但是当它离线时,它不会调用onDataChange。

这段代码即使在离线时也能很好地工作。

mDatabase = FirebaseDatabase.getInstance()
            .getReference()
            .child(Database.PLACES)
            .child(((BaseActivity) getActivity()).getUserId());

Timber.d("TRYING TO GET PLACES");
mDatabase.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        Timber.d("GOT PLACES");
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Timber.w(databaseError.toException());
    }
});

它给了我这个日志:

D/PlaceListFragment:207: TRYING TO GET PLACES
D/Persistence: Starting transaction.
D/Persistence: Saved new tracked query in 1ms
D/Persistence: Transaction completed. Elapsed: 3ms
D/EventRaiser: Raising 1 event(s)
D/EventRaiser: Raising /places/JLC2zqpSMFfYEGaUAfSTCHA2K4k1: VALUE: null
D/PlaceListFragment:211: GOT PLACES

但是,使用完全相同的代码,但更改 DatabaseReference(路径)它给了我这个日志并且不起作用。

D/AnalysisActivity$2$override:144: TRYING TO GET READS
D/Persistence: Starting transaction.
D/Persistence: Saved new tracked query in 0ms
D/Persistence: Loaded a total of 0 rows for a total of 0 nodes at /reads/-KdiPFBrnEBHaPGCbP86 in 1ms (Query: 1ms, Loading: 0ms, Serializing: 0ms)
D/Persistence: Transaction completed. Elapsed: 13ms

是什么让我相信即使事务完成,也有一些东西可以阻止调用此事件。

会发生什么?

Obs:我的用户已通过 firebase auth correclty 进行身份验证,并且我已在我的应用程序设置中进行了配置:

FirebaseDatabase.getInstance().setPersistenceEnabled(true);
FirebaseDatabase.getInstance().setLogLevel(Logger.Level.DEBUG);

【问题讨论】:

  • 您共享的代码中的任何内容都不会写入数据。这意味着 Firebase 正在从其缓存中返回数据。由于它以空快照触发,因此您尝试读取的值显然从未被缓存。
  • 但是,它至少应该触发 onCancelled 事件,不是吗?因为我需要一种方法来处理这个回调......
  • onCancelled 在您没有权限时会被触发。客户端根本不知道您是否有权限(因为它没有连接到服务器),也不知道是否有值(因为它从未缓存过位置)。

标签: android firebase firebase-realtime-database


【解决方案1】:

您共享的代码中的任何内容都不会写入数据。这意味着 Firebase 正在从其缓存中返回数据。由于它以空快照触发,因此您尝试读取的位置显然从未被缓存。由于这个原因,它不能调用onDataChange

onCancelled 方法会在你没有权限时触发。客户端根本不知道你是否有权限(因为它没有连接到服务器),所以它也不能调用onCancelled

因此,如果不知道该位置的值(如果有)或您是否有权限,则不会触发任何方法。重新连接到后端后,将触发正确的事件。

如果您知道这是一个新位置,您可能希望通过向其写入null准备该位置。这样,缓存将包含该位置的值,onDataChange 将使用不带值的快照调用。

【讨论】:

  • 谢谢@frank-van-puffelen。使用 null 启动新位置就可以了。
  • @frank-van-puffelen : 请问一下,如果我不知道叶子是新的还是旧的,我该怎么办?
猜你喜欢
  • 2020-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-29
  • 2020-04-21
相关资源
最近更新 更多