我试图列出ID数组中给出的所有文档。
规则:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
function isSignedIn() {
return request.auth.uid != null;
}
function checkUserId(orgId) {
return ('user_id' in resource.data.keys() && request.auth.uid==resource.data.user_id)
|| orgId in get(/databases/$(database)/documents/user/$(request.auth.uid)).data.organisationIds;
}
function checkAdminToken() {
return 'lectusAdmin' in request.auth.token.keys() && request.auth.token.lectusAdmin
}
match /organisation/{document=**} {
allow read, update, delete: if isSignedIn() && (checkUserId(document) || checkAdminToken()); // This is line 20
allow create: if isSignedIn();
}
}
}
我的Angular 10代码是:
this.organisationCollection = this._angularFirestore.collection<Organisation>('organisation');
this.organisations = this.organisationCollection.valueChanges({idField: 'id'});
我试图在集合-where
中添加一个.where('id', 'in', org.organisationIds)
,其中id
是检查org.organisationIds
数组的文档ID(我认为是)。同样,我不确定是否需要这样做,因为规则应该能够弄清楚这一点。
我收到错误消息--false for 'list' @ L20
,即-allow read, update, delete: if isSignedIn() && (checkUserId(document) || checkAdminToken());
当我尝试使用orginisation/<document ID>
来获取文档但无法列出它们时,此方法很好用。
任何帮助将不胜感激。
答案 0 :(得分:1)
您遇到的问题是Firestore security rules are not filters。请仔细阅读该文档。规则将不检查整个查询结果集中每个文档的内容-不能按照Firestore的要求进行扩展。 Firestore每个集合最多可扩展数十亿甚至更多文档。阅读和检查每个文档都是不可能的。
您的查询声明它要所有“组织”集合中的文档。由于规则无法使用您现在拥有的检查(必须检查每个文档,甚至其他文档的内容)来确保每个文档都可读,因此它们只会使整个查询失败。
使查询生效的唯一方法是,如果它符合规则要求。例如,如果您的规则要求用户的ID必须等于文档中的字段“ user_id”,则您需要在查询的该字段上添加用户的UID作为过滤器。但是您仍然不能根据资源文档中的字段来get()
规则中的其他文档(因为它仍然不会读取每个文档来进行检查)。