英文:
How do I write a Firestore security rule so that only someone who is listed as an admin can perform certain actions and everyone else can only read?
问题
以下是翻译好的部分:
结构如下:
/groups/{groupID}
在这个{groupID}记录中,它将具有以下字段(最后一个是子集合)。此集合中列出的adminUID
应该具有额外的权限。
groupID
groupName
adminUID
adminUsername
createDate
creatorUID
creatorUsername
initialGroupCreate
groupMembersSubcollection
对于静态字段,管理员应该能够:
- 使用这些静态字段创建{groupID}记录,但不能修改/删除
组的成员只能读取,但不能写入/删除。
对于子集合,管理员应该能够:
- 在groupMembersSubcollection中创建/删除任意数量的记录;不能修改
组的成员只能读取这个子集合中的记录。
英文:
The structure is:
/groups/{groupID}
Inside this {groupID} record, it will have the following fields (the last one is a subcollection). The adminUID
listed in this collection is the one who should have the extra permissions.
groupID
groupName
adminUID
adminUsername
createDate
creatorUID
creatorUsername
initialGroupCreate
groupMembersSubcollection
For the static fields, the admin should be able to:
- create the {groupID} record with these static fields, cannot modify/delete
The members of the group can only read but not write/delete.
For the subcollection, the admin should be able to:
- create/delete any number of records in the groupMembersSubcollection; cannot modify
The members of the group can only read records in this sub-collection.
答案1
得分: 1
以下是您要翻译的内容:
假设您的Firestore集合结构如下,而且您的groupMembersSubcollection
中的文档以group Members
user.uid
为文档ID:
Firestore数据库
└── groups -(集合)
└── {groupID}-文档ID
├── groupID
├── groupName
├── adminUID
├── adminUsername
├── createDate
├── creatorUID
├── creatorUsername
├── initialGroupCreate
└── groupMembersSubcollection -(子集合)
然后您所需的安全规则如下:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// function to check member or not
function isMemerOrNot(groupId) {
return exists(/databases/$(database)/documents/groups/$(groupId)/groupMembersSubcollection/$(request.auth.uid)); // Not verified
}
// Rule 1: Static fields in the groups collection
match /groups/{groupId} {
allow read : if request.auth != null && isMemerOrNot(groupId);
allow create: if request.resource.data.keys().hasAll([ //making sure all fields are there while creating this document
'groupID',
'groupName',
'adminUID',
'adminUsername',
'createDate',
'creatorUID',
'creatorUsername',
'initialGroupCreate']) &&
request.resource.data.adminUID == request.auth.uid; // allowed only for admins
allow update, delete: if false; // No updates or deletes allowed
}
// Rule 2: groupMembersSubcollection
match /groups/{groupId}/groupMembersSubcollection/{userId} {
allow read: if request.auth != null && request.auth.uid == userId // Members can read the subcollection
allow create, delete: if
request.auth.uid == get(/databases/$(database)/documents/groups/$(groupId)).data.adminUID;
allow update: if false; // No updates allowed for subcollection documents
}
}
}
解释:
-
对于规则1:
read
规则仅允许已认证用户,也是成员的用户(对于isMemberOrNot函数,您需要检查是否存在具有该uid的成员,您可以使用exists(/databases/$(database)/documents/groups/$(groupId)/groupMembersSubcollection/$(request.auth.uid));
这个技巧来自访问其他文档,但您需要确保子集合已经存在具有成员文档ID的文档)create
规则仅允许管理员使用指定的静态字段创建文档。update
和delete
规则设置为false
,以便任何人都不能修改/删除。
-
对于规则2:
read
规则允许已认证用户和组成员读取groupMembersSubcollection
中的文档,借助其user.uid
。create
和delete
规则允许管理员(使用父文档中的adminUID
来识别)在groupMembersSubcollection
中创建或删除文档。update
规则设置为false
,以禁止对groupMembersSubcollection
中的文档进行任何更新。
参考:
英文:
Assuming your Firestore collection structure is as follows and your documents inside groupMembersSubcollection
saved with document id as group Members
user.uid
:
Firestore Database
└── groups - (Collection)
└── {groupID}- Document Id
├── groupID
├── groupName
├── adminUID
├── adminUsername
├── createDate
├── creatorUID
├── creatorUsername
├── initialGroupCreate
└── groupMembersSubcollection - (sub-collection)
Then your desired security rules will be as follows :
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// function to check member or not
function isMemerOrNot(groupId) {
return exists(/databases/$(database)/documents/groups/$(groupId)/groupMembersSubcollection/$(request.auth.uid)); // Not verified
}
// Rule 1: Static fields in the groups collection
match /groups/{groupId} {
allow read : if request.auth != null && isMemerOrNot(groupId);
allow create: if request.resource.data.keys().hasAll([ //making sure all fields are there while creating this document
'groupID',
'groupName',
'adminUID',
'adminUsername',
'createDate',
'creatorUID',
'creatorUsername',
'initialGroupCreate']) &&
request.resource.data.adminUID == request.auth.uid; // allowed only for admins
allow update, delete: if false; // No updates or deletes allowed
}
// Rule 2: groupMembersSubcollection
match /groups/{groupId}/groupMembersSubcollection/{userId} {
allow read: if request.auth != null && request.auth.uid == userId // Members can read the subcollection
allow create, delete: if
request.auth.uid == get(/databases/$(database)/documents/groups/$(groupId)).data.adminUID;
allow update: if false; // No updates allowed for subcollection documents
}
}
}
Explanation :
- For Rule 1 :
- The
read
rule will only allow authenticated users which are also members(for isMemberOrNot function you need to check whether a member with that uid exist or not you can useexists(/databases/$(database)/documents/groups/$(groupId)/groupMembersSubcollection/$(request.auth.uid))
technique from Access other documents but you need to be sure that the subcollection have the member documentId as a document already exist )
; - The
create
rule allows only the admin to create a document in the groups collection with the specified static fields. - The
update
anddelete
rules are set tofalse
so that no one cannot modify/delete
- For Rule 2 :
- The
read
rule allows authenticated users and Group Members to read the documents in thegroupMembersSubcollection
with the help of theiruser.uid
. - The
create
anddelete
rules allow the admin (usingadminUID
from parent document to identify) to create or delete documents in thegroupMembersSubcollection
- The
update
rule is set tofalse
to disallow any updates to the documents in thegroupMembersSubcollection
.
Reference :
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论