Firebase Firestore访问规则:资源数据匹配与查询适配问题咨询
首先明确一点:你当前的安全规则和未添加过滤条件的排序查询不兼容,会触发权限拒绝错误,下面详细分析原因和解决方案:
核心冲突原因
你的allow read规则要求只有文档的ownerUid与当前用户的auth.uid一致时才能读取,但你的查询collection("teams").orderBy("teamName")没有添加任何过滤条件。Firestore的安全规则设计是必须让数据库能提前验证整个查询结果集的权限合法性,而不是在返回结果时逐个检查文档(这会导致严重的性能问题)。因为你的查询没有限定ownerUid,Firestore无法确认返回的所有文档都符合规则,所以会直接拒绝这个查询请求。
解决方案:让查询与规则条件匹配
你需要在查询中添加与规则对应的过滤条件,确保查询只获取当前用户作为所有者的团队数据。修改后的Java代码如下:
// 获取当前登录用户的UID String currentUserUid = FirebaseAuth.getInstance().getCurrentUser().getUid(); // 添加ownerUid过滤后的排序查询 Query query = FirebaseFirestore.getInstance() .collection("teams") .whereEqualTo("ownerUid", currentUserUid) .orderBy("teamName");
这样修改后,查询的过滤条件和安全规则的权限要求完全匹配,Firestore可以高效验证权限,查询就能正常执行了。
额外的重要注意事项
1. 修复过于宽松的写入规则
你当前的allow write: if true;规则非常危险,这意味着任何知道你Firebase项目ID的人都可以修改、删除甚至添加任意团队文档。建议把写入规则也限制为仅文档所有者可操作:
service cloud.firestore { match /databases/{database}/documents { match /teams/{teamId} { allow read: if resource.data.ownerUid == request.auth.uid; allow write: if request.auth.uid == resource.data.ownerUid; // 如果是创建新文档,还可以添加验证:确保创建时的ownerUid是当前用户 // allow create: if request.auth.uid == request.resource.data.ownerUid; } } }
如果需要支持团队成员编辑,可以进一步扩展规则,但基础的所有者权限是必须的。
2. 复合索引的创建
当你同时使用whereEqualTo和orderBy时,Firestore需要对应的复合索引才能高效执行查询。第一次运行修改后的查询时,你会在Logcat中看到一个包含索引创建链接的错误信息,点击链接即可自动创建所需的索引,或者你也可以手动在Firestore控制台的「索引」页面创建。
内容的提问来源于stack exchange,提问作者NT93

