2017-02-24 65 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:請問,如果我不知道葉子是新的還是舊的,我該怎麼辦? –