Firestore规则问题:已共享用户无法访问照片文档排查
问题原因及解决方案
1. Firestore规则逻辑完全颠倒
你写的规则是在判断「文档所有者的邮箱是否在该文档的shared数组里」,这逻辑完全反了——正常应该是「当前登录用户的邮箱是否在shared数组里,或者用户本身就是文档所有者」。原规则只会在owner的邮箱被自己加入shared列表时才允许访问,这显然不符合需求。
修正后的规则:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /photos/{photo} { allow read if: // 用户是文档所有者,或者邮箱在shared数组中 request.auth.token.email == resource.data.emailOwner || request.auth.token.email in resource.data.shared; } } }
2. 查询代码的条件错误
你的查询用了whereField("emailOwner", arrayContains: user.email),但emailOwner是单个字符串类型的字段,arrayContains是专门用来查询数组类型字段是否包含指定元素的方法,这里完全用错了字段。
你需要查询的是两类文档:
- 自己作为所有者的文档(
emailOwner等于当前用户邮箱) - 被共享给自己的文档(
shared数组包含当前用户邮箱)
修正后的Swift查询代码(并行查询后合并去重):
func getItems() async throws -> [Item] { guard let userEmail = user.email else { throw NSError(domain: "AuthError", code: 0, userInfo: [NSLocalizedDescriptionKey: "用户未登录"]) } // 查询自己所有的照片 let ownerQuery = photoCollection.whereField("emailOwner", isEqualTo: userEmail) // 查询共享给自己的照片 let sharedQuery = photoCollection.whereField("shared", arrayContains: userEmail) // 并行执行两个查询 let (ownerSnapshot, sharedSnapshot) = try await (ownerQuery.getDocuments(), sharedQuery.getDocuments()) // 转换并合并结果 var items: [Item] = [] items += try ownerSnapshot.documents.compactMap { try $0.data(as: Item.self) } items += try sharedSnapshot.documents.compactMap { try $0.data(as: Item.self) } // 按ID去重,避免自己的照片同时在shared列表里重复出现 let uniqueItems = Array(Set(items)) return uniqueItems }
额外注意点
- 确保Firestore规则中启用了身份验证,可在规则顶部添加基础校验:
allow read, write: if request.auth != null; - 检查shared数组中存储的邮箱格式是否和用户登录的邮箱完全一致(大小写、拼写错误都会导致匹配失败)
内容的提问来源于stack exchange,提问作者matteog
相关产品推荐
相关产品推荐

