Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何同步读取Firebase实时数据库值?_Android_Firebase_Firebase Realtime Database - Fatal编程技术网

Android 如何同步读取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

我正在使用firebase实时数据库,据我所知,您必须使用

 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时是如何编写代码的。在开始一个新的聊天组之前,我曾经检查过一个用户的现有聊天记录,我发现这个答案很有用。