2017-02-24 48 views
0

我对Firebase ValueEventListener有一个非常奇怪的情况。离线时未调用Firebase onDataChange

当手机连接到互联网时,它工作正常。但是当它离线时,它不会调用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 

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

会发生什么?

观测值:我的用户进行身份验证火力权威性correclty和我的应用程序设置我已经这样配置:在代码

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

您共享的代码中没有内容写入数据。这意味着Firebase正在从其缓存中返回数据。由于它以空的快照触发,显然你试图读取的值从未被缓存。 –

+0

但是,它至少应该触发取消事件,不应该?因为我需要一种方法来处理这个回调...... –

+0

当你没有权限时会触发'onCancelled'。客户端根本不知道你是否有权限(因为它没有连接到服务器),也不知道是否有值(因为它没有缓存该位置)。 –

回答

1

没有你共享写入数据。这意味着Firebase正在从其缓存中返回数据。由于它以空的快照触发,显然你试图读取的位置从未被缓存。由于这个原因,它不能调用onDataChange

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

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

如果您知道这是一个新的位置,你可能会写null它要黄金该位置。这样缓存将包含该位置的值,并且onDataChange将被调用且没有值的快照。

+0

谢谢@ frank-van-puffelen。使用null初始化新位置工作得很好。 –

+0

@ frank-van-puffelen:请问,如果我不知道叶子是新的还是旧的,我该怎么办? –