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

Firestore查询不存在用户文档未触发addOnFailureListener反而崩溃怎么办

问题原因
  • Firestore 的 get() 方法的 addOnFailureListener 仅会捕获请求级别的错误,比如网络异常、权限不足、请求参数非法等场景。你删除对应文档后,请求本身已经成功发送并拿到了服务器返回结果,只是返回的文档为空,所以会走 addOnSuccessListener 回调,不会触发失败监听。
  • 崩溃的直接来源是 addOnSuccessListener 内部的非空断言 !!:当目标文档不存在时,document.toObject(User::class.java) 会返回 null,你用 !! 强制要求非空,就会直接抛出 NullPointerException,这个异常是在成功回调内部抛出的,自然不会被失败回调捕获。
修复方案

你可以按以下步骤修改代码,避免崩溃同时捕获这类文档不存在的异常:

  1. 先判断返回的 document 是否存在,再做后续转换
  2. 避免使用非空断言 !!,改用 Kotlin 空安全语法处理边界场景
  3. 可在成功回调内部加 try-catch 兜底所有未预判的异常

修改后的参考代码如下:

fun getUserDetail(fragment: HomeFragment) {
    mFireStore.collection(Constants.USERS)
        .document(getCurrentUserID())
        .get()
        .addOnSuccessListener { document ->
            if (document.exists()) {
                val user = document.toObject(User::class.java)
                user?.let {
                    fragment.successUserDetail(it)
                } ?: run {
                    // 文档存在但转换为User对象失败的处理逻辑
                    Log.d("Tag", "文档数据格式异常,无法转换为User对象")
                    fragment.hideProgressDialog()
                }
            } else {
                // 文档不存在的处理逻辑,比如跳转到资料填写页
                Log.d("Tag", "对应用户文档不存在")
                fragment.hideProgressDialog()
            }
        }
        .addOnFailureListener { e ->
            Log.d("Tag", e.message ?: "未知请求错误")
            fragment.hideProgressDialog()
        }
}

如果需要统一捕获成功回调内部的所有异常,也可以在回调外层加 try-catch 块:

.addOnSuccessListener { document ->
    try {
        // 原有业务逻辑
    } catch (e: Exception) {
        Log.d("Tag", "处理用户数据时出错:${e.message}")
        fragment.hideProgressDialog()
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 10:57:01