Firestore安全规则下写入失败,如何通过用户ID完成认证?
问题分析与解决方案
核心问题1:安全规则路径不匹配
你的Firestore安全规则仅对/users/{userID}集合配置了权限,但代码中实际写入的是wordOfDay集合,规则未覆盖这个路径,导致权限校验失败。
核心问题2:认证方式错误
Firestore安全规则中的request.auth.uid依赖Firebase Auth当前登录用户的会话信息,而非你手动存在UserDefaults里的ID。只有通过Firebase Auth完成登录,Firestore客户端才会自动将认证信息附加到请求中,规则才能获取到request.auth.uid。
修复步骤
1. 更新Firestore安全规则
新增wordOfDay集合的权限规则,确保仅当前认证用户能操作自己UID对应的文档:
service cloud.firestore { match /databases/{database}/documents { // 保留原users集合规则 match /users/{userID} { allow create; allow read, write: if request.auth.uid == userID; } // 添加wordOfDay集合的权限规则 match /wordOfDay/{userID} { allow create, write, read: if request.auth.uid == userID; } } }
2. 确保应用通过Firebase Auth完成用户认证
在用户注册/登录流程中,使用Firebase Auth SDK提供的方法(如createUser(withEmail:password:)或signIn(withEmail:password:))完成认证,不要仅依赖UserDefaults存储ID。Firebase Auth会自动管理用户会话,确保Firestore请求携带正确的认证信息。
3. 修正SwiftUI代码中的UID获取逻辑
替换手动读取UserDefaults的方式,直接从Firebase Auth获取当前用户的UID:
guard let userID = Auth.auth().currentUser?.uid else { // 处理用户未登录的场景,例如弹窗提示登录 return } db.collection("wordOfDay").document(userID).setData([ "email": inputText, "word": Array(commonWords)[commonWordIndex].foreign ?? "", "date": todaysDate ]) { error in if let error = error { print("数据写入失败:\(error.localizedDescription)") } else { print("数据写入成功") } }
额外提示
- 若需持久化用户ID,可在Auth登录成功后将
currentUser?.uid存入UserDefaults,但读取时优先检查Auth.auth().currentUser,避免UserDefaults中的值与实际Auth状态不一致。 - 若仍遇到权限错误,可在Firebase控制台的Firestore > 规则页面使用"规则模拟器"测试请求,排查具体的权限拒绝原因。
内容的提问来源于stack exchange,提问作者Tycho Systems
相关产品推荐
相关产品推荐

