了解Cloud Firestore的安全规则的限制

时间:2017-12-03 14:50:07

标签: firebase google-cloud-firestore firebase-security-rules

我正在为我的Firestore数据库编写安全规则,我到了可能写了太多支票并且授权自动失败的地步。

例如,特定路径的规则是

service cloud.firestore {
  match /databases/{database}/documents {
    match /pending/{userId} {
      match /rate/{vendorId}/events/{eventId}/ratings/{rateId} {
        allow write: if request.auth.uid == userId
            && exists(/databases/$(database)/documents/vendors/$(vendorId)) // The vendor must exist
            && exists(/databases/$(database)/documents/users/$(userId)/subscriptions/$(vendorId)) // The user must be subscribed to the vendor
            && exists(/databases/$(database)/documents/vendors/$(vendorId)/events/$(eventId)) //  The event must exist
            && !exists(/databases/$(database)/documents/vendors/$(vendorId)/events/$(eventId)/ratings/$(userId)) // The user must not have already voted for the event
      }
    }
  }
}

写入/待定/ {userId} / rate / {vendorId} / events / {eventId} / ratings / {rateId}

时适用这些规则

删除一个或多个规则组合会使一切都重新运作。 我阅读了有关10个开发人员定义的函数here的限制的文档,但是exists和get被列为服务定义的,不应计算在内。即使他们是,我在这里只使用五个。

是否有更有效的方法来检查相同的字段?如何计算单条线在达到10个函数限制时的计算量?

由于

1 个答案:

答案 0 :(得分:3)

此处的Firebase PM:目前,我们将给定规则评估中的get()exists()次呼叫的数量限制为三次,这就是为什么您在添加第四次后看到行为失败的原因。我会确保文档已适当更新以包含此信息。

编辑(4/2/18):现在记录了这些限制:https://firebase.google.com/docs/firestore/security/rules-structure#security_rule_limits

编辑(5/14/18):我们将限制增加到10:https://firebase.google.com/docs/firestore/security/rules-structure#security_rule_limits

get()exists()调用比“正常”规则评估的计算成本更高,我们希望确保评估时间的严格限制,以便不会减慢传入的请求。我很确定我们可以增加大于3的数字,但要注意我们会查找所有这些键/值,并且可能需要更长的时间/成本来评估每个请求。

请注意,在这种特定情况下,您可以通过三次调用来执行此操作:

service cloud.firestore {
  match /databases/{database}/documents {
    match /pending/{userId} {
      match /rate/{vendorId}/events/{eventId}/ratings/{rateId} {
        // Only allow a document to be created
        allow create:
            // The user must not have already voted for the event
            if request.auth.uid == userId
            && request.auth.uid == rateId
            // The vendor must exist
            && exists(/databases/$(database)/documents/vendors/$(vendorId)) 
            // The user must be subscribed to the vendor
            && exists(/databases/$(database)/documents/users/$(userId)/subscriptions/$(vendorId)) 
            //  The event must exist
            && exists(/databases/$(database)/documents/vendors/$(vendorId)/events/$(eventId));
        // Not necessary unless you want to allow updates
        allow update: if ...;
      }
    }
  }
}