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

Swift将Firestore请求从Completion改为Async/Await后解码报错求助

问题分析与解决办法

错误根源

你的Async/Await代码和原Completion回调代码有两个核心差异,导致了这个错误:

  1. 错误处理逻辑不同:原代码用try?尝试解码,失败时直接return静默忽略错误;而新代码用try强制抛出解码错误,之前被隐藏的解码问题现在直接暴露了出来。
  2. 缺少文档存在性检查:原代码先判断snapshot是否存在,不存在就直接返回;但新代码跳过了这个检查——如果指定uid的用户文档不存在,snapshot.data(as:)会因为没有可解码的数据,抛出"Cannot get keyed decoding container -- found null value instead"这个模糊错误。

修正后的代码

func fetchUser(withUid uid: String) async throws -> UserModel {
    let snapshot = try await Firestore.firestore().collection("users").document(uid).getDocument()
    
    // 先检查文档是否存在
    guard snapshot.exists else {
        throw NSError(domain: "FirestoreError", code: -1, userInfo: [NSLocalizedDescriptionKey: "指定用户不存在"])
    }
    
    // 尝试解码并处理解码错误
    do {
        return try snapshot.data(as: UserModel.self)
    } catch {
        throw NSError(domain: "FirestoreError", code: -2, userInfo: [
            NSLocalizedDescriptionKey: "用户数据解码失败",
            NSUnderlyingErrorKey: error
        ])
    }
}

关键修正点

  • 新增snapshot.exists检查,提前拦截文档不存在的情况,抛出明确的错误信息,避免后续解码时出现模糊的null错误
  • 简化嵌套的do-catch结构,让代码更易读
  • 对解码错误进行包装,保留底层错误信息,方便上层调用时定位具体问题

额外说明

原Completion版本的静默失败逻辑在实际开发中其实存在隐患——调用者无法知道用户数据获取失败的原因。Async/Await版本通过抛出错误的方式,强制要求上层处理这些异常情况,反而更符合Swift的错误处理规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 23:22:39