您可以创建交易,并放弃它,那么的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在某段时间后断开连接。我如何强制一次手动更新? –
这是一种不方便的行为,它使测试几乎不可能。 –