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

Swift使用Codable映射Firestore自定义对象时getDocument调用报错

Swift + Firebase Codable 映射拉取用户数据报错修复

背景

正在练习使用Swift实现自定义对象映射,计划通过Codable协议替换所有手动映射逻辑,该特性接触不久但实用价值很高。当前项目需要拉取用户信息,确保用户的所有数据(包括自定义对象FavouriteItems)都存储在Firebase对应的User Document中。

现有代码定义

User Model 结构体

import SwiftUI
import FirebaseFirestoreSwift

struct UserModel: Identifiable, Codable{
    @DocumentID var id: String?
    var username : String
    var pic : String
    var bio: String
    var uid : String
    var isVerified: Bool
    var favouriteItems: [FavouriteItems]
}

Item 结构体

import SwiftUI
import FirebaseFirestoreSwift
import Firebase


struct Item: Identifiable, Codable {
    
    @DocumentID var id: String?
    var item_name: String
    var item_type: String
    var item_image: String
    var item_details: String
    var item_uid : String
    var didFavourite: Bool? = false
    var isFavourite: Bool = false  
}

FavouriteItems 结构体

import SwiftUI
import FirebaseFirestoreSwift

//MARK: Make Hashable (See Tag Example)?
struct FavouriteItems: Identifiable, Codable {
    
    @DocumentID var id: String?
    var item: Item
}

初始实现的fetchUser函数

func fetchUser(uid: String, completion: @escaping (UserModel) -> ()){
    let db = Firestore.firestore()

    let docRef = db.collection("Users").document(uid).getDocument(as: UserModel.self) { result in

        switch result {
        case .success(let user):
            print("UserModel: \(user)")
            DispatchQueue.main.async {
                completion(user)
            }

        case .failure(let error):
            print("Error decoding UserModel: \(error)")
            // 待补充错误处理逻辑
        }
    }
}

报错信息

所有报错均指向代码行:
let docRef = db.collection("Users").document(uid).getDocument(as: UserModel.self) { result in

具体报错:

  • Cannot convert value of type 'UserModel.Type' to expected argument type 'FirestoreSource'
  • Contextual closure type '(DocumentSnapshot?, Error?) -> Void' expects 2 arguments, but 1 was used in closure body
  • Incorrect argument label in call (have 'as:_:', expected 'source:completion:')

附项目Podfile配置截图:
Podfile配置截图

问题原因

编译器没有识别到FirebaseFirestoreSwift提供的Codable扩展解码方法,回退匹配了Firestore原生的getDocument(source:completion:)方法,导致参数类型、标签全部不匹配。
触发该问题的常见原因:

  1. fetchUser函数所在的文件没有导入FirebaseFirestoreSwift模块,无法读取Codable相关的方法扩展
  2. 安装完Pod依赖后,打开的是.xcodeproj格式的项目文件,而非CocoaPods生成的.xcworkspace文件,导致依赖没有正确加载
  3. 多余的let docRef =赋值:带Codable解码的getDocument(as:completion:)方法本身为异步无返回值方法,不需要接收返回值

修复方案

  1. 在fetchUser函数所在文件的顶部添加导入语句:import FirebaseFirestoreSwift
  2. 关闭当前项目,找到项目目录下的.xcworkspace文件双击打开,确认依赖加载正常
  3. 移除多余的返回值接收代码,修正后的fetchUser实现如下:
import Firebase
import FirebaseFirestoreSwift // 必须导入该模块才能使用Codable解码扩展

func fetchUser(uid: String, completion: @escaping (UserModel) -> ()){
    let db = Firestore.firestore()

    db.collection("Users").document(uid).getDocument(as: UserModel.self) { result in
        switch result {
        case .success(let user):
            print("UserModel: \(user)")
            DispatchQueue.main.async {
                completion(user)
            }
        case .failure(let error):
            print("Error decoding UserModel: \(error)")
            // 后续补充错误处理逻辑
        }
    }
}

额外注意

当前定义的UserModel、FavouriteItems、Item均已正确遵守Codable协议,只要Firestore中存储的字段名和结构体属性名完全一致,就可以正常完成解码。如果存在字段名不统一的情况,可以通过给对应结构体添加CodingKeys枚举做自定义映射。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 15:36:21