从 Firebase 侦听器发出状态 - Kotlin Flow

edw*_*rek 3 android kotlin kotlin-coroutines

我想使用 Kotlin Flow 来处理 FirebaseAuth 状态。我知道下面的代码是错误的,但我不知道如何修复它。我试过了channelFlow,它总是在我想要的时候崩溃,send或者offer

   fun registerFlow(email: String, password: String) = flow {
    emit(AuthState.Loading)
    firebaseAuth.createUserWithEmailAndPassword(email, password)
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                CoroutineScope(Dispatchers.IO).launch {      
                    emit(AuthState.Success(task.result?.user))
            } }else {
                  emit(AuthState.Error(task.exception))
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

}

里面的协程Listener抛出

z E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1
Process: pl.rybson.musicquiz, PID: 26578
java.lang.IllegalStateException: Flow invariant is violated:
        Emission from another coroutine is detected.
        Child of StandaloneCoroutine{Active}@4903a45, expected child of StandaloneCoroutine{Completed}@988059a.
        FlowCollector is not thread-safe and concurrent emissions are prohibited.
        To mitigate this restriction please use 'channelFlow' builder instead of 'flow'
Run Code Online (Sandbox Code Playgroud)

我使用时的错误 send()

FATAL EXCEPTION: DefaultDispatcher-worker-1
Process: pl.rybson.musicquiz, PID: 27105
kotlinx.coroutines.channels.ClosedSendChannelException: Channel was closed
Run Code Online (Sandbox Code Playgroud)

Geo*_*ung 5

flow端部时的代码块运行完成。

您可以使用集成使其成为挂起函数,而不是使用回调。

fun registerFlow(email: String, password: String) = flow {
    emit(AuthState.Loading)
    val result = firebaseAuth.createUserWithEmailAndPassword(email, password).await()
    if (result.isSuccessful) {     
        emit(AuthState.Success(result.result?.user))
    } else {
        emit(AuthState.Error(result.exception))
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 但请记住,这是一次性操作,不会提供连续更新。但在这个用例中,这不是问题 (2认同)