SwiftUI中Firestore子集合查询数据读取异常问题求助
问题解决:Firestore解码错误"The data couldn't be read because it's missing."
你遇到的错误本质是Firestore文档字段与Swift的FoodItem结构体Codable定义不匹配,可能是字段名不一致、必填字段缺失、数据类型不匹配,或是文档ID未正确映射导致的。以下是针对性的解决步骤:
1. 检查字段名与映射
Firestore字段名与Swift结构体属性名大小写完全敏感,如果Firestore使用蛇形命名(如item_name)而Swift用驼峰命名(itemName),必须通过CodingKeys手动映射:
struct FoodItem: Codable, Identifiable { var id: String var itemName: String var itemDescription: String var photoURL: String? // 改为可选类型,防止字段缺失 var itemPrice: Int var DDPSnack: Bool var alcohol: Bool var gardenGraze: Bool var plantBased: Bool // 根据Firestore实际字段名调整映射 enum CodingKeys: String, CodingKey { case id case itemName = "itemName" // 若Firestore字段名一致可省略,否则替换为实际名称 case itemDescription = "itemDescription" case photoURL = "photoURL" case itemPrice = "itemPrice" case DDPSnack = "DDPSnack" case alcohol = "alcohol" case gardenGraze = "gardenGraze" case plantBased = "plantBased" } }
2. 处理可选字段
如果Firestore中某些字段可能不存在(如photoURL可能为空),将结构体对应的属性改为可选类型(添加?),避免因字段缺失触发解码失败。
3. 手动映射文档ID
Firestore默认不会将文档ID自动赋值给FoodItem的id属性,需在解码后手动设置:
class FoodViewModel: ObservableObject { // ... 其他代码不变 ... func fetchData() { foodRef?.getDocuments { snapshot, error in // ... 错误处理代码不变 ... self.foodItems = documents.compactMap { document in do { var foodItem = try document.data(as: FoodItem.self) foodItem.id = document.documentID // 手动绑定文档ID return foodItem } catch { // 打印具体错误和文档ID,方便排查 print("解码文档 \(document.documentID) 失败: \(error)") return nil } } } } }
4. 验证数据类型一致性
确保Firestore中字段类型与Swift结构体完全匹配:
itemPrice必须是数字类型(Int),不能是字符串- 布尔字段(如
alcohol)必须是布尔类型,不能是字符串或数字
5. 额外排查点
- 确认传入的
venueID对应Firestore中存在的venues文档 - 检查Firestore安全规则,确保当前用户有权限读取
food子集合数据
内容的提问来源于stack exchange,提问作者Jason Tremain
相关产品推荐
相关产品推荐

