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配置截图:
问题原因
编译器没有识别到FirebaseFirestoreSwift提供的Codable扩展解码方法,回退匹配了Firestore原生的getDocument(source:completion:)方法,导致参数类型、标签全部不匹配。
触发该问题的常见原因:
- fetchUser函数所在的文件没有导入
FirebaseFirestoreSwift模块,无法读取Codable相关的方法扩展 - 安装完Pod依赖后,打开的是
.xcodeproj格式的项目文件,而非CocoaPods生成的.xcworkspace文件,导致依赖没有正确加载 - 多余的
let docRef =赋值:带Codable解码的getDocument(as:completion:)方法本身为异步无返回值方法,不需要接收返回值
修复方案
- 在fetchUser函数所在文件的顶部添加导入语句:
import FirebaseFirestoreSwift - 关闭当前项目,找到项目目录下的
.xcworkspace文件双击打开,确认依赖加载正常 - 移除多余的返回值接收代码,修正后的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
相关产品推荐
相关产品推荐

