Android 如何同步读取Firebase实时数据库值?
我正在使用firebase实时数据库,据我所知,您必须使用Android 如何同步读取Firebase实时数据库值?,android,firebase,firebase-realtime-database,Android,Firebase,Firebase Realtime Database,我正在使用firebase实时数据库,据我所知,您必须使用 DatabaseReference.addValueEventListener 从firebase数据库中读取值 默认情况下,addValueEventListener是异步的。我需要同步阅读。对于FireBase存储,对于上传文件时的相同问题,我可以使用 UploadTask.TaskSnapshot await = Tasks.await(uploadTask); 而不是使用 uploadTask.addO
DatabaseReference.addValueEventListener
从firebase数据库中读取值
默认情况下,addValueEventListener
是异步的。我需要同步阅读。对于FireBase存储,对于上传文件时的相同问题,我可以使用
UploadTask.TaskSnapshot await = Tasks.await(uploadTask);
而不是使用
uploadTask.addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
@Override
public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
}
})
uploadTask.addOnCompleteListener(新的OnCompleteListener(){
@凌驾
未完成的公共void(@NonNull任务){
}
})
如上图所示,
addValueEventListener
是否有类似的同步替代方案 尝试从异步API同步返回值不是一个好主意。但是,如果您的块已经与主线程异步,则可以使用CountDownLatch
和wait
回调响应
例如:
CountDownLatch latch = new CountDownLatch(1);
uploadTask.addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>(){
@Override
public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
//Handle response
latch.countDown();
}
});
latch.await();
CountDownLatch闩锁=新的CountDownLatch(1);
uploadTask.addOnCompleteListener(新的OnCompleteListener(){
@凌驾
未完成的公共void(@NonNull任务){
//处理响应
倒计时();
}
});
satch.wait();
大多数firebase方法返回任务实例。因此,我们可以很容易地在非主线程中等待它们来获得结果(而不是实现onCompleteListener并运行到“回调地狱”)
但是我没有找到一种返回任务的getValue方法。我发现在问题的评论中提到了blogpost。在经历了这些之后,我为自己编写了一个getValue扩展函数
internal fun DatabaseReference.getValue(): Task<DataSnapshot> {
val dbSource = TaskCompletionSource<DataSnapshot>()
addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
dbSource.setResult(snapshot)
}
override fun onCancelled(error: DatabaseError) {
dbSource.setException(error.toException())
}
})
return dbSource.task
}
internal fun DatabaseReference.getValue():任务{
val dbSource=TaskCompletionSource()
addListenerForSingleValueEvent(对象:ValueEventListener{
覆盖数据更改(快照:DataSnapshot){
dbSource.setResult(快照)
}
覆盖已取消(错误:DatabaseError){
dbSource.setException(错误.toException())
}
})
返回dbSource.task
}
此外,如果有任何更正,请在注释中通知:)尝试从异步API同步返回值,这不是一个好主意。您应该按照预期异步处理API。你想以这种方式得到答案吗?我这样做是因为我在一个已经异步的块中使用此函数。是否有此函数的同步版本?在应用程序的主线程中调用同步方法可能会完全冻结你的应用程序,这是一种糟糕的用户体验。在Android上,您也可能最终得到应用程序没有响应的对话框。这就是您想要的吗?
addValueEventListener
可以多次触发,因此无法完成。但是addSingleValueEventListener
可以完成。请参阅,了解如何将SingleValueEvent的addListenerForSingleValueEvent
转换为您可以等待的任务。这非常好。我想知道开发人员在处理服务器端逻辑和使用firebase admin sdk时是如何编写代码的。在开始一个新的聊天组之前,我曾经检查过一个用户的现有聊天记录,我发现这个答案很有用。