Swift使用compactMap解析Firebase Firestore嵌套数据类型失败原因排查
解析失败的核心问题有4处:
- 字段名不匹配:Firestore文档中存储商品集合的字段名为
item,但你在mainStruct中定义的对应属性名是items,Codable自动解析会因为键名不一致失败。
- 字段名不匹配:Firestore文档中存储商品集合的字段名为
- 嵌套结构类型不匹配:Firestore中的
item字段是键值对格式的字典(key为商品名如Ball、RugbyBall,value为商品属性),但你定义的itemListStruct包裹的是数组类型,字典和数组无法自动映射。
- 嵌套结构类型不匹配:Firestore中的
- 属性类型不匹配:Firestore中
iNum的存储值为12.99是浮点型,你在itemStruct中将其定义为Int,类型不匹配会直接导致解析失败;同时iP的存储值为整数,你定义为Double虽可兼容但建议按需调整。
- 属性类型不匹配:Firestore中
- 多余的嵌套结构体:
itemListStruct完全没有必要,可直接用[String: ItemStruct]类型对应Firestore的字典结构。
- 多余的嵌套结构体:
修正后的代码
结构体定义
// 遵循Swift命名规范,结构体首字母大写 struct MainStruct: Identifiable, Codable { @DocumentID var id: String? = UUID().uuidString var date: Date // 字段名和Firestore保持一致,类型直接用字典对应map结构 var item: [String: ItemStruct] } struct ItemStruct: Identifiable, Codable { @DocumentID var id: String? = UUID().uuidString // 类型调整为和Firestore存储一致的Double var iNum: Double var iP: Int var iQ: Int }
解析逻辑
原有解析逻辑无需修改即可正常运行,如果后续需要把item字典转为数组使用,可参考下方处理方式:
self.items = documents.compactMap { queryDocumentSnapshot -> MainStruct? in return try? queryDocumentSnapshot.data(as: MainStruct.self) } // 可选:将item字典转为商品数组 if let mainData = self.items.first { let itemArray = mainData.item.map { $0.value } // 也可保留key作为商品名:let itemArray = mainData.item.map { (name: $0.key, data: $0.value) } }
内容的提问来源于stack exchange,提问作者mdav132
相关产品推荐
相关产品推荐

