2017-03-17 33 views
0

請看下面的例子:Firebase數據庫:如果客戶端處於脫機狀態,顯然規則不適用?

我一個test/節點上寫一個值,我已經建立了一個規則,將允許寫,只有當「(新價值)等於(舊值+ 1 )「,即newData.val() == data.val() + 1

假設test/節點的初始值爲0

如果客戶去離線並執行以下命令:他又回到網上時

testRef.setValue(1); 
testRef.setValue(2); 
testRef.setValue(3); 
testRef.setValue(4); 
testRef.setValue(5); 

然後,5將在數據庫中寫入的值,但我不知道我明白爲什麼,因爲5 != 0 + 1。我想這是因爲緩存了本地數據庫中以前的值,但不幸的是,這不是我想要實現的結果。我希望服務器拒絕該值,因爲它不遵循數據庫的規則。

有沒有辦法做到這一點?

或有任何其他的解決辦法,這樣我可以執行以下操作:

testRef.setValue(1);- >寫值到本地數據庫- >檢查,如果值如下在線數據庫的規則- >如果該值不遵守規則,或者如果我們不能確認,因爲我們處於離線狀態,然後從本地數據庫

回答

0

刪除的價值我認爲你的問題「下線」是指客戶端沒有連接。在我的測試中,我通過啓用飛行模式進行了模擬。

火力地堡離線功能在user guide描述。只要有一個細節,那就是你的問題重要的是:

的火力地堡實時數據庫客戶端會自動的 隊列中所有的寫操作被同時您的應用程序離線執行... 當應用程序重新獲得連接,所有操作都會發送到Firebase實時數據庫服務器的 。

您可以使用下面的代碼看到此行爲,該行爲爲setValue()調用添加了完成偵聽器。在我的測試中,我將設備置於飛行模式(離線),運行代碼,然後禁用飛行模式返回在線狀態。爲每個setValue()生成一條日誌消息,確認寫入操作在連接重新建立時排隊併發送。這就解釋了爲什麼寫入滿足您的驗證規則:客戶端不會發送一個寫入請求,其最終值爲5,它會以原始遞增值發送五個請求。

您可以確認該規則的工作方式再次運行測試,而不首先test值重置回0每次寫操作將失敗。

此代碼還演示了火力地堡客戶端如何處理當客戶端離線所做的更改,以及後來被安全規則拒絕。在離線狀態下,更改在客戶端緩存中進行,回調將使用新的(未驗證的)值進行觸發。之後,當客戶端上線並且更改被服務器拒絕時,onDataChange()會再次以先前的值觸發。

final DatabaseReference ref = FirebaseDatabase.getInstance().getReference("test"); 

ref.addValueEventListener(new ValueEventListener() { 
    @Override 
    public void onDataChange(DataSnapshot dataSnapshot) { 
     Log.d(TAG, "onDataChange: test=" + dataSnapshot.getValue(Integer.class)); 
    } 
    @Override 
    public void onCancelled(DatabaseError databaseError) { 
     throw databaseError.toException(); 
    } 
}); 

final DatabaseReference.CompletionListener completionListener = 
     new DatabaseReference.CompletionListener() { 
    @Override 
    public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) { 
     if (databaseError == null) { 
      Log.d(TAG, "setValue() Success"); 
     } else { 
      Log.d(TAG, "setValue() Failed " + databaseError.getMessage()); 
     } 
    } 
}; 

ref.setValue(1, completionListener); 
ref.setValue(2, completionListener); 
ref.setValue(3, completionListener); 
ref.setValue(4, completionListener); 
ref.setValue(5, completionListener); 
+0

謝謝,我可以理解,但是我個人希望有一個選項可以從本地緩存中刪除值,如果由於缺少Internet連接而無法驗證規則。我需要這個原因是因爲我正在開發一個協作應用程序,並且一些節點可以由一個以上的用戶訪問。在任何情況下,如果沒有任何Internet連接,是否有解決方法可以從本地緩存中刪除值?有點像超時? (即如果服務器無法訪問5秒鐘,則從緩存中刪除所有掛起的寫入/本地值。 – MScott

+0

AFAIK沒有API可以刪除掛起的寫入。請參閱Firebaser FvP的這個答案:http://stackoverflow.com/a/34625545/4815718。可能最好的做法是[監控連接狀態](https://firebase.google.com/docs/database/android/offline-capabilities#section-connection-state),並且只允許寫入連接時。 –

相關問題