您可以創建交易,並放棄它,那麼的onComplete將在網上(n線數據)或脫機(緩存數據)
我以前創建僅當數據庫有連接器LOMNG足以做到同步其工作函數調用。我通過添加超時來解決問題。我會研究這個並測試它是否有效。也許在未來,當我得到自由的時候,我將創建Android的lib和發佈,但那時它是在科特林代碼:
/**
* @param databaseReference reference to parent database node
* @param callback callback with mutable list which returns list of objects and boolean if data is from cache
* @param timeOutInMillis if not set it will wait all the time to get data online. If set - when timeout occurs it will send data from cache if exists
*/
fun readChildrenOnlineElseLocal(databaseReference: DatabaseReference, callback: ((mutableList: MutableList<@kotlin.UnsafeVariance T>, isDataFromCache: Boolean) -> Unit), timeOutInMillis: Long? = null) {
var countDownTimer: CountDownTimer? = null
val transactionHandlerAbort = object : Transaction.Handler { //for cache load
override fun onComplete(p0: DatabaseError?, p1: Boolean, data: DataSnapshot?) {
val listOfObjects = ArrayList<T>()
data?.let {
data.children.forEach {
val child = it.getValue(aClass)
child?.let {
listOfObjects.add(child)
}
}
}
callback.invoke(listOfObjects, true)
}
override fun doTransaction(p0: MutableData?): Transaction.Result {
return Transaction.abort()
}
}
val transactionHandlerSuccess = object : Transaction.Handler { //for online load
override fun onComplete(p0: DatabaseError?, p1: Boolean, data: DataSnapshot?) {
countDownTimer?.cancel()
val listOfObjects = ArrayList<T>()
data?.let {
data.children.forEach {
val child = it.getValue(aClass)
child?.let {
listOfObjects.add(child)
}
}
}
callback.invoke(listOfObjects, false)
}
override fun doTransaction(p0: MutableData?): Transaction.Result {
return Transaction.success(p0)
}
}
在代碼,如果超時設置,那麼我設置計時器這將通過中止調用事務。即使在離線狀態下,此事務也會被調用,並且會提供聯機或緩存數據(在此功能中,這些數據緩存的可能性很高)。 然後我稱成功交易。如果我們從Firebase數據庫獲得響應,將只會調用OnComplete
。我們現在可以取消定時器(如果不爲空)並將數據發送到回調。
該實現使開發人員99%確信數據來自緩存或處於聯機狀態。
如果你想進行離線更快(以不顯然數據庫沒有連接超時的愚蠢等),然後檢查是否數據庫使用上述功能之前連接:
DatabaseReference connectedRef = FirebaseDatabase.getInstance().getReference(".info/connected");
connectedRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
boolean connected = snapshot.getValue(Boolean.class);
if (connected) {
System.out.println("connected");
} else {
System.out.println("not connected");
}
}
@Override
public void onCancelled(DatabaseError error) {
System.err.println("Listener was cancelled");
}
});
謝謝。我現在從鏈接的答案瞭解到.. –
感謝您的完美插圖。但keepSynced(true)和addValueEventListener將始終保持打開的連接。與keepSynced(false)相反,addListenerForSingleValueEvent將允許firebase在某段時間後斷開連接。我如何強制一次手動更新? –
這是一種不方便的行爲,它使測試幾乎不可能。 –