英文:
Firestore Security Rules: How to perform a collection query within firestore rules?
问题
我的数据库结构如下:
/sites/{siteId}/pages/{pageId}
现在,如果在pages集合中已经有3个已发布的页面,我不希望允许更新page的isPublished
字段。
为了实现这一点,我需要使用“isPublished”、“==”和true过滤器查询pages集合,然后检查文档数量。
在Firestore安全规则中,有没有一种方法可以实现这个?
match /sites/{siteId}/pages/{pageId} {
allow update: if request.resource.data.isPublished == true ? canPublishPage(siteId) : true
}
function canPublishPage(siteId) {
// 如何检查当前已发布的页面数量?
}
英文:
My database structure is as follows:
/sites/{siteId}/pages/{pageId}
now I don't want to allow update the isPublished
field of a page if there are already 3 published pages in the pages collection.
For this I would need to query the pages collection with "isPublished", "==", true filter and check the amount of docs.
Is there a way in firestore security rules to achieve this
match /sites/{siteId}/pages/{pageId} {
allow update: if request.resource.data.isPublished == true ? canPublishPage(siteId) : true
}
function canPublishPage(siteId) {
// how can I check number of published page at the moment?
}
答案1
得分: 2
无法从规则中计算此类聚合数据。
相反,您需要执行以下操作:
1)在siteId
文档内部添加一个计数器,在每次创建页面时递增。您需要在这里使用批处理以原子方式更新站点计数器并创建页面。在您的pageId
规则中使用getAfter
函数来验证计数器是否正确递增:
function isCounterIncremented(siteId) {
let counterbefore = get(/databases/$(database)/documents/sites/$(siteId)).data.counter;
let counterafter = getAfter(/databases/$(database)/documents/sites/$(siteId)).data.counter;
return counterafter == counterbefore + 1
}
2)在页面使用get
规则更新时,检查规则中的计数器:
function canPublishPage(siteId) {
return get(/databases/$(database)/documents/sites/$(siteId)).data.counter < 3;
}
英文:
There is no way to calculate this kind of aggregate data from the rules.
Instead you will have to:
-
Add a counter within the
siteId
document, incremented at each page creation. You will want to use a batch here to update the site counter and create the page both in an atomic way. Use thegetAfter
function in your rules forpageId
to verify the counter is properly incremented:function isCounterIncremented(siteId) { let counterbefore = get(/databases/$(database)/documents/sites/$(siteId)).data.counter; let counterafter = getAfter(/databases/$(database)/documents/sites/$(siteId)).data.counter; return counterafter == counterbefore + 1 }
-
Check that counter from the rules when a page is updated using
get
in your rules:function canPublishPage(siteId) { return get(/databases/$(database)/documents/sites/$(siteId)).data.counter < 3; }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论