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

使用FirebaseFirestoreSwift读取自定义对象遇FirestoreSource参数错误

问题解决:Firestore getDocument 报错 expected argument type 'FirestoreSource'

核心错误原因

Firebase 8.x版本的getDocument(as:completion:)方法必须显式传入source参数,这是旧版本API的强制要求,和你参考的新版文档(默认省略source参数)不兼容。

分步修复方案

1. 补充FirestoreSource参数

在getDocument调用时添加source参数,可选值对应不同的读取策略:

  • .default:优先读取本地缓存,缓存无数据则请求服务器
  • .cache:仅读取本地缓存数据
  • .server:强制从服务器拉取最新数据

修改后的调用代码:

docRef.getDocument(as: User.self, source: .default) { result in
    switch result {
    case .success(let user):
        print(user)
    case .failure(let error):
        print("Error decoding: \(error)")
    }
}

2. 修复Document ID的错误获取

Auth.auth().currentUser是User?类型对象,不能直接作为文档ID,需要提取它的uid属性:

guard let currentUserId = Auth.auth().currentUser?.uid else {
    // 处理用户未登录的异常情况
    fatalError("用户未登录")
}
let docRef = db.collection("users").document(currentUserId)

3. 修正异步函数的返回值问题

你的getUser()方法声明返回User,但getDocument是异步操作,无法同步返回结果。推荐两种改造方式:

方式一:使用Completion Handler

func getUser(completion: @escaping (Result<User, Error>) -> Void) {
    guard let currentUserId = Auth.auth().currentUser?.uid else {
        completion(.failure(NSError(domain: "Auth", code: -1, userInfo: [NSLocalizedDescriptionKey: "用户未登录"])))
        return
    }
    let docRef = db.collection("users").document(currentUserId)
    docRef.getDocument(as: User.self, source: .default) { result in
        completion(result)
    }
}

// 调用示例
getUser { result in
    switch result {
    case .success(let user):
        print(user)
    case .failure(let error):
        print("获取用户失败:\(error)")
    }
}

方式二:使用Async/Await(iOS 15+支持)

Firebase 8.x支持async/await语法,改造成异步函数更简洁:

func getUser() async throws -> User {
    guard let currentUserId = Auth.auth().currentUser?.uid else {
        throw NSError(domain: "Auth", code: -1, userInfo: [NSLocalizedDescriptionKey: "用户未登录"])
    }
    let docRef = db.collection("users").document(currentUserId)
    return try await docRef.getDocument(as: User.self, source: .default)
}

// 调用示例
Task {
    do {
        let user = try await getUser()
        print(user)
    } catch {
        print("获取用户失败:\(error)")
    }
}

额外优化建议

你的User结构体中family属性没有默认值,如果Firestore文档中该字段缺失,解码会失败。建议添加默认值:

var family: [Family] = []

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 13:25:38