我在Cloud Firestore中设置了以下规则。结构为:
/users/{userId}/years/{year}/**
。如果该年份设置了year
标志,我想拒绝对closed
文档及其子集合及其文档进行任何写操作。
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, update: ...;
allow delete: ....;
allow create: ...
match /years/{year} {
allow read, create: ...;
allow delete: ...;
allow update: if request.auth.uid == userId && !resource.data.closed
match /{document=**} {
allow read: ...;
allow write: if get(/databases/$(database)/documents/users/$(userId)/years/$(year)).data.closed == false
&& request.auth.uid == userId;
}
}
}
}
}
年度级别的规则似乎有效。但在此之下,无论标记状态如何,get
调用中的所有请求都会失败(在模拟器和应用程序中)。 Firestore文档中没有几个有关如何使用变量的示例-可以从上层继承变量吗?或者访问下面的任何文档时如何获得年份的标志字段?
[更新/解决方案]
经过大量的搜索并运行了更多的模拟之后,事实证明问题出在根本没有closed
标志的情况下。在 undefined 中,firestore规则引擎似乎不如JS引擎具有优势。引发一个异常,等同于规则失败。必须检查该属性是否存在,然后测试该值。而且因为即使在函数中也无法使用局部变量,所以这意味着两个 get -s而不是一个...
match /years/{year} {
match /{document=**} {
allow read: ...;
allow write: if !(getYearData().keys().hasAll(['closed']) && getYearData().closed) && request.auth.uid == userId;
}
function getYearData() {
return get(/databases/$(database)/documents/users/$(userId)/years/$(year)).data;
}
}
这个问题仍然需要更好的解决方案。