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

Kotlin Firebase任务失败时continueWith回调仍触发问题求解

问题原因

你遇到的逻辑异常核心是两个问题:

  1. 对Tasks API的回调触发逻辑理解有误:continueWith属于非状态感知的回调,无论上游的Firestore获取任务成功还是失败,它都会被触发,不会因为上游任务抛异常就跳过执行。只有addOnSuccessListener、addOnFailureListener是严格绑定任务终态、只在对应状态触发的回调。
  2. 代码存在隐藏逻辑bug:你调用的db.collection(customGameName).document()没有传入指定文档ID,会生成一个指向随机ID的空文档引用,查询这个引用几乎永远拿不到有效数据,完全达不到校验游戏名是否存在的目的。
正确实现方式

基础写法(对应你当前的业务场景)

在continueWith内部首先校验上游任务状态,失败就直接抛出异常透传给下游的失败监听器,只有确认任务成功、文档真实存在时才执行业务逻辑:

// 注意:请根据你的实际存储结构修正文档引用,示例假设游戏数据存储在games集合下,文档ID为游戏名
db.collection("games")
    .document(customGameName)
    .get()
    .continueWith { task ->
        // 上游任务失败直接抛异常,跳过后续业务逻辑
        if (!task.isSuccessful) {
            throw task.exception ?: RuntimeException("Failed to fetch game info")
        }
        val snapshot = task.result
        // get请求成功不代表文档存在,必须额外校验
        if (!snapshot.exists()) {
            throw RuntimeException("Game does not exist")
        }
        // 校验通过才执行业务逻辑
        if (!gameslist.contains(customGameName)) {
            gameslist.add(customGameName)
            SavedPreference.setGamesList(this, gameslist)
            adapter.notifyDataSetChanged()
        } else {
            Toast.makeText(this, "$customGameName is in the list already!", Toast.LENGTH_SHORT).show()
        }
    }
    .addOnFailureListener {
        // 所有上游抛出的异常都会统一走到这里处理
        Toast.makeText(this, "$customGameName not exist!", Toast.LENGTH_SHORT).show()
        gameslist.remove(customGameName)
        SavedPreference.setGamesList(this, gameslist)
        adapter.notifyDataSetChanged()
    }

continueWithTask适用场景

只有当你需要在拿到当前任务结果后,串接执行另一个异步任务(比如更新其他Firestore数据、调用其他异步接口)时,才需要用continueWithTask,写法逻辑和上面一致,只是成功分支返回下一个异步任务的Task对象即可:

.continueWithTask { task ->
    if (!task.isSuccessful) {
        throw task.exception ?: RuntimeException("Failed to fetch game info")
    }
    val snapshot = task.result
    if (!snapshot.exists()) throw RuntimeException("Game does not exist")
    // 串接下一个异步操作:比如更新用户最近访问记录
    db.collection("user_data").document(currentUserId).update("lastVisitedGame", customGameName)
}
注意事项
  • 所有continueWith/continueWithTask回调中,必须第一时间校验上游任务的isSuccessful状态,不要默认上游任务一定执行成功
  • Firestore的get任务只要和后端完成通信就算成功,哪怕查询的文档不存在,必须通过result.exists()判断文档是否真实存在
  • 无参的document()方法仅用于生成新文档的随机ID引用,查询已有数据时必须传入明确的文档ID

内容的提问来源于stack exchange,提问作者endy aris

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 10:54:21