SwiftUI中Firebase Firestore无法保存数据问题求助
Firestore无法保存数据问题排查
现象

代码实现
模型定义
struct Box: Identifiable, Hashable, Codable { @DocumentID var id: String? var boxName: String var boxSize: String enum CodingKeys: String, CodingKey { case id case boxName case boxSize } var dictionary: [String: Any] { let data = (try? JSONEncoder().encode(self)) ?? Data() return (try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any]) ?? [:] } }
ViewModel实现
class BoxViewModel: ObservableObject { @Published var box: Box private var db = Firestore.firestore() init(box: Box = CashBox(boxName: "", boxSize: "")) { self.box = box } private func addNewBox(_ box: Box){ print("the name \(box.boxName)") let _ = db.collection("Box") .addDocument(data: box.dictionary) } func addBox() { self.addNewBox(box) } func setBoxData(boxName: String, boxSize: String){ self.box.boxName = boxName self.box.boxSize = boxSize } }
视图代码
struct CashBoxView: View { @State var boxName = "" @State var boxSize = "" @EnvironmentObject var boxViewModel: BoxViewModel var body: some View { Text("Enter box name") TextField("", text: $boxName) Text("Enter box size") TextField("", text: $boxSize) Button(action: { boxViewModel.setBoxData(boxName: boxName, boxSize: boxSize) boxViewModel.addBox() }) { Text("Done") } } }
排查方向
从你的描述看,box.boxName能正常打印,说明对象数据没问题,以下是几个核心排查点:
EnvironmentObject注入验证
确认父视图已通过.environmentObject(BoxViewModel())完成ViewModel注入。如果未注入,@EnvironmentObject会直接触发崩溃,但既然能打印数据,大概率已注入,可再检查注入逻辑是否覆盖当前视图层级。Firestore权限规则
默认Firestore规则仅允许认证用户读写数据,如果当前未做用户登录,数据会被拦截。可临时修改规则测试(测试后务必改回安全规则):rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if true; } } }字典转换逻辑问题
当前通过JSONEncoder转Data再转字典的方式存在不确定性,比如@DocumentID标记的可选id可能编码异常。建议手动构建字典替代:var dictionary: [String: Any] { var dict: [String: Any] = [ "boxName": boxName, "boxSize": boxSize ] if let id = id { dict["id"] = id } return dict }错误捕获缺失
当前addDocument未处理错误,添加回调获取具体失败原因:db.collection("Box").addDocument(data: box.dictionary) { error in if let error = error { print("保存失败原因: \(error.localizedDescription)") } else { print("数据保存成功") } }ViewModel初始化笔误
初始化代码中写的是CashBox(boxName: "", boxSize: ""),但你的模型是Box,这里是明显笔误,需改为Box(boxName: "", boxSize: ""),避免初始化异常。
内容的提问来源于stack exchange,提问作者Rahaf
相关产品推荐
相关产品推荐

