You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Kotlin协程实现Firebase匿名登录的无网阻塞问题求助

问题原因

无网络时,Firebase的signInAnonymously()返回的Task不会主动终止——既不完成也不抛出异常,导致await()一直处于挂起状态,无法进入后续的if-else逻辑。这是因为Firebase匿名登录在离线场景下默认会等待网络恢复,不会立即返回失败结果。

解决方案:给await()添加超时机制

用Kotlin协程的withTimeoutOrNull设置超时时间,超时后取消挂起的协程并返回null,以此终止等待逻辑,处理离线或长时间无响应的情况。

修改后的FirebaseHelper.kt代码

fun getUserId() = flow {
    val loginResult = withTimeoutOrNull(5000) { // 设置5秒超时,可根据需求调整时长
        Firebase.auth.signInAnonymously().await()
    }

    if (loginResult?.user != null && !loginResult.user?.uid.isNullOrEmpty()) {
        emit("Successful")
    } else {
        emit("Failed") // 超时或登录失败都会触发该分支
    }
}

补充说明

  • withTimeoutOrNull超时后返回null,不会抛出异常,适合优雅处理超时场景;如果希望超时直接抛出异常,可改用withTimeout,但需额外捕获TimeoutCancellationException。
  • 超时时间建议根据实际网络环境调整,比如设置3-10秒。
  • 可进一步添加异常捕获,处理Firebase登录可能出现的其他异常(如权限问题):
fun getUserId() = flow {
    try {
        val loginResult = withTimeoutOrNull(5000) {
            Firebase.auth.signInAnonymously().await()
        }

        if (loginResult?.user != null && !loginResult.user?.uid.isNullOrEmpty()) {
            emit("Successful")
        } else {
            emit("Failed")
        }
    } catch (e: Exception) {
        emit("Failed: ${e.message}")
    }
}

Repository.kt优化(可选)

原代码中collect后重复emit的逻辑可简化:

suspend fun getUserId(): Flow<String> {
    return firebaseHelper.getUserId().map { result ->
        if (result == "Successful") "Successful" else "Task unsuccessful"
    }
}

内容的提问来源于stack exchange,提问作者Mr. Techie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 19:10:18