callbackFlow未返回任何内容android kotlin

callbackFlow未返回任何内容android kotlin,android,firebase,kotlin,firebase-realtime-database,Android,Firebase,Kotlin,Firebase Realtime Database,我想用协程实现firebase实时数据库,所以我需要使用flow,因为firebase只接受回调。问题是.collect{}块永远不会执行 这是我的密码 @ExperimentalCoroutinesApi override suspend fun getProduct(barcode: String): ProductItem? { return withContext(Dispatchers.Default) { println("Hi") va

我想用协程实现firebase实时数据库,所以我需要使用flow,因为firebase只接受回调。问题是.collect{}块永远不会执行 这是我的密码

   @ExperimentalCoroutinesApi
override suspend fun getProduct(barcode: String): ProductItem? {
    return withContext(Dispatchers.Default) {
        println("Hi")
        var item: ProductItem? = null
        productFlow(barcode).collect {
        //this never gets called
            print("Getting product")
            item = it
        }
        println("Ending product request ${item?.name}")
        Log.i("GetProduct",item?.name)
        item
    }
}
@ExperimentalCoroutinesApi
private fun productFlow(barcode: String): Flow<ProductItem?> = callbackFlow {
    val database = FirebaseDatabase.getInstance()
    val productRef = database.getReference("products/$barcode")
    val callback = object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            for(snapshot in dataSnapshot.children){

                Log.i("Source", snapshot.value.toString())
            }
            val product = dataSnapshot.getValue(ProductItem::class.java)
            Log.i("Source",product?.name) //everything is good until here

            sendBlocking(dataSnapshot.getValue(ProductItem::class.java)) //after this i dont get anything on the collect{} block
        }

        override fun onCancelled(databaseError: DatabaseError) {
            println("cancelling")
            sendBlocking(null)
        }
    }
    try {
        productRef.addListenerForSingleValueEvent(callback)
    } catch (e: FirebaseException) {
        println("Firebase exception")
        sendBlocking(null)
    }
    awaitClose{
        println("Closing")
        productRef.removeEventListener(callback)
    }
}
@experimentalRoutinesAPI
覆盖产品(条形码:字符串):ProductItem?{
返回withContext(Dispatchers.Default){
println(“Hi”)
变量项:ProductItem?=null
产品流(条形码)。收集{
//这个从来没人打过电话
打印(“获取产品”)
item=it
}
println(“结束产品请求${item?.name}”)
Log.i(“GetProduct”,项?.name)
项目
}
}
@实验常规
private fun productFlow(条形码:字符串):Flow=callbackFlow{
val database=FirebaseDatabase.getInstance()
val productRef=database.getReference(“产品/$barcode”)
val callback=object:ValueEventListener{
覆盖数据更改(dataSnapshot:dataSnapshot){
for(dataSnapshot.children中的快照){
Log.i(“Source”,snapshot.value.toString())
}
val product=dataSnapshot.getValue(ProductItem::class.java)
Log.i(“Source”,product?.name)//在这里之前一切都很好
sendBlocking(dataSnapshot.getValue(ProductItem::class.java))//在此之后,我在collect{}块上没有得到任何信息
}
覆盖已取消(databaseError:databaseError){
println(“取消”)
发送阻塞(空)
}
}
试一试{
productRef.addListenerForSingleValueEvent(回调)
}捕获(e:FirebaseException){
println(“Firebase例外”)
发送阻塞(空)
}
等待结束{
println(“交割”)
productRef.removeEventListener(回调)
}
}

首先,我建议使用
catch
方法检查是否存在错误。其次,对于
callbackflow
我记得我使用了
offer()
而不是
sendBlocking

我刚刚尝试了它,它也不起作用,我在新的try-catch上也没有发现艾米错误,所以我不知道:(然后,您可以在coroutines github上打开一个问题:/现在我想起来了,因为您只有一个评估,对于您的情况,使用
suspendCancelableCoroutine
比使用
callbackFlow
更容易。谢谢,我稍后会尝试,我今天早上说channel.close()在sendBlocking语句之后,因为没有来自firebase的onComplete回调,我只需要检索一次。但我会尝试一下,然后回来