我在firestore中有一组规则
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document} {
allow read: if true;
allow write: if isTrustworthy();
}
match /stores/{storeId}{
match /{document} {
allow read: if true;
allow write: if isTrustworthy();
}
match /departures/{departureId} {
allow read: if true;
allow write: if !(resource.data.locked);
}
}
function isTrustworthy(){
return isSignedIn() && emailVerified();
}
function isSignedIn() {
return request.auth != null;
}
function emailVerified() {
return request.auth.token.email_verified;
}
}
}
,但我得到一个错误时设置,更新或删除在出发的路径。
。
this.afs.collection('stores').doc(this.auth.store)
.collection('departures')
.doc(element.shipping.trackingNumber.toString())
.set({"test":true})
文档不存在,但如果文档存在,它也不会工作,独立于参数"locked"我得到了以下错误:
ERROR ERROR: Uncaught (in promise): FirebaseError: [code=permission-denied]: Missing or sufficientpermissions .
FirebaseError: Missing or sufficientpermissions .
我需要的是,如果文档有一个参数"locked"如果设置为true,则不能删除、更新,也不能设置{merge:true}选项。
任何帮助都将非常感激。
你的规则和代码有几个问题:
- 在
create
上,resource.data
不存在 - 在
update
或delete
上,locked
字段可能不存在 - 当你使用
set
在Firestore中创建或更新文档时,你必须添加选项{merge: true}
,更新文档而不是覆盖它,以防它已经存在。
试试这个:
-
代码:
this.afs.collection('stores').doc(this.auth.store) .collection('departures') .doc(element.shipping.trackingNumber.toString()) .set({"test":true}, {merge: true})
-
规则:
match /departures/{departureId} { allow read: if true; allow create: if true; allow update, delete: if !resource.data.get("locked", false); }
我在我的规则中添加了一组函数,使编写这样的规则更容易:
function existing() {
return resource.data;
}
function resulting() {
return request.resource.data;
}
function matchField(fieldName) {
return existing()[fieldName] == resulting()[fieldName];
}
resource
表示被访问的文档,request.resource
表示该文档的新数据。有了这些,您可以引用现有或传入文档上的值。
matchField
在与各种声明/角色结合使用时非常有用,可以保护文档的部分不被更改。
在您的情况下,您可以检查特定字段的状态"locked
",例如某种形式的:
match /whatever/points/to/the/doc {
allow write: if !existing().locked
}
(我使用了几十个这样的函数,主要是为了使我的规则看起来几乎像文本)