Firestore权限错误排查:iOS/watchOS Apple登录场景权限不足问题
可能的遗漏点
1. Auth状态监听的时序问题
你在addStateDidChangeListener回调里,没有使用回调传入的user参数,反而调用Auth.auth().currentUser获取用户。虽然两者通常一致,但在auth状态切换的瞬间(比如Apple登录刚完成、跨设备同步auth状态时),currentUser可能存在更新延迟,导致发起Firestore请求时,请求携带的auth信息还未同步,触发权限校验失败。
2. Firestore离线缓存干扰
如果应用处于离线状态,Firestore会优先读取本地缓存。若缓存的文档是在之前的auth状态下存储的,当auth状态更新后,缓存的读取可能不符合当前规则,导致权限错误。这种情况会表现为“时好时坏”(在线时正常,离线时出错)。
3. Apple登录的跨设备同步延迟
iOS和watchOS之间的Firebase Auth状态同步依赖于Keychain共享,若同步未完成,watchOS端发起请求时可能携带旧的(甚至无效的)auth凭证,触发权限失败。
排查与修复步骤
修正Auth状态获取方式:直接使用回调传入的
user参数,替代Auth.auth().currentUser,确保拿到实时更新的auth状态:handle = firebaseAuth.addStateDidChangeListener { [weak self] auth, user in guard let self, let user else { return } Task { let db = Firestore.firestore() let doc = try await db.collection("users").document(user.uid).getDocument() } }开启Firestore调试日志:在App启动时添加日志配置,查看详细的权限校验过程,定位具体请求问题:
Firestore.firestore().enableLogging(true)控制台会输出Firestore请求的详细日志,包括auth凭证、请求路径、规则校验的具体结果,帮助确认是否是auth信息未正确携带。
检查文档存在性与规则匹配:虽然规则允许读写自己的用户文档,但如果文档尚未创建,
getDocument会返回“文档不存在”,但不会触发权限错误。可以在Firebase控制台手动检查对应uid的users文档是否存在,排除文档缺失导致的间接问题。验证跨设备Auth同步:在watchOS端,确保已正确配置Keychain共享(开启
Keychain Sharing能力,添加Firebase的Keychain组),保证Auth状态能在iOS和watchOS之间实时同步。
查看Firestore记录归属者的方法
通过文档ID判断:你的规则中
users集合的文档ID就是用户的uid,所以文档ID对应的就是该记录的归属用户。在Firebase控制台的Firestore页面,打开users集合,文档名称即为用户uid,可对应到Auth面板中的用户。自定义字段存储:如果需要更直观的归属信息,可以在用户文档中添加
uid、displayName等字段,存储用户的标识信息,这样在控制台查看文档时能直接看到归属者的相关信息。
内容的提问来源于stack exchange,提问作者lewis

