我有以下规则:
match /suuntoAppAccessTokens/{userName} {
allow create: if request.auth.uid != null && request.auth.token.firebase.sign_in_provider != 'anonymous';
match /tokens/{userID} {
allow read, write, create, update, delete: if request.auth.uid == userID && request.auth.token.firebase.sign_in_provider != 'anonymous';
}
}
match /{path=**}/tokens/{userID} {
allow read, write, create, update, delete: if request.auth.uid == userID;
}
这意味着当前用户应该有权访问路径/suuntoAppAccessTokens/dimitrioskanellopoulos/tokens/{userID}
。
但是,当我这样查询集合组时:
return this.afs.collectionGroup('tokens').snapshotChanges();
我收到一个权限错误。
直接在tokes / {userID}下获取文档可以正常工作。
我该怎么做,以便当前用户可以运行collectionGroup查询并根据我的规则获取允许其获取的项目?
答案 0 :(得分:2)
您的规则期望安全规则将过滤所有tokens
集合中的所有文档,以便仅读取当前用户的文档。使用安全规则是不可能的。 安全规则不是过滤器。来自documentation:
在编写查询以检索文档时,请记住安全性 规则不是过滤器-查询全部或全部。为了节省您的时间, 资源,Cloud Firestore根据潜在查询评估查询 结果集,而不是所有您的实际字段值 文件。如果查询可能返回文档, 客户端没有读取权限,整个请求失败。
您需要将查询更改为客户端仅请求完全希望当前用户可读的文档。不幸的是,我无法确定您当前的模式是否可行。文档{userId}的ID不能在集合组查询中用于过滤文档。因此,您都必须确保满足以下两个条件:
我建议使用令牌将用户的uid存储在文档中,该令牌与规则中的{userId}相同。您可以像这样查询它:
collectionGroup('tokens').where("uid", "==", uid)
确保客户端正确传入uid
此外,您还需要确保规则按照完全相同的条件授予访问权限:
match /{path=**}/tokens/{userID} {
allow read, write, create, update, delete:
if request.auth.uid == resource.data.uid;
}
仅当文档的uid字段与身份验证uid相同时才允许访问该文档,而这正是客户端所要求的。