Firestore安全规则:如何在Firestore规则中执行集合查询?

huangapple go评论70阅读模式
英文:

Firestore Security Rules: How to perform a collection query within firestore rules?

问题

我的数据库结构如下:

/sites/{siteId}/pages/{pageId}

现在,如果在pages集合中已经有3个已发布的页面,我不希望允许更新pageisPublished字段。

为了实现这一点,我需要使用“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:

  1. 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 the getAfter function in your rules for pageId 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
    }
    
  2. 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 &lt; 3;    
    }
    

huangapple
  • 本文由 发表于 2023年5月26日 15:56:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76338777.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定