Kotlin Firebase任务失败时continueWith回调仍触发问题求解
问题原因
你遇到的逻辑异常核心是两个问题:
- 对Tasks API的回调触发逻辑理解有误:
continueWith属于非状态感知的回调,无论上游的Firestore获取任务成功还是失败,它都会被触发,不会因为上游任务抛异常就跳过执行。只有addOnSuccessListener、addOnFailureListener是严格绑定任务终态、只在对应状态触发的回调。 - 代码存在隐藏逻辑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
相关产品推荐
相关产品推荐

