Firebase安全规则get()和getAfter()之间的区别

问题描述 投票:0回答:1

在文档中,它说:

使用get()和exists()函数,您的安全规则可以根据数据库中的其他文档评估传入请求。

多数民众赞成我,这个例子对我有意义:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      // Make sure a 'users' document exists for the requesting user before allowing any writes to the 'cities' collection
      allow create: if exists(/databases/$(database)/documents/users/$(request.auth.uid))

      // Allow the user to delete cities if their user document has the
      // 'admin' field set to 'true'
      allow delete: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true
    }
  }
}

但是它说

对于写入,您可以使用getAfter()函数在事务或批处理写入完成之后但在事务或批处理提交之前访问文档的状态。

我可能仍然不完全理解这个概念。我的问题是:

  1. 为什么它必须使用getAfter()进行事务或批量写入,我们可以只使用get()吗?
  2. 如果你必须使用getAfter()进行事务或批量写入,这是否意味着你仍然需要get()进行正常写入?它们如何同时存在?

谢谢。

firebase google-cloud-firestore firebase-security-rules
1个回答
2
投票

首先,请记住,写入的安全规则在数据库中的任何内容被写入更改之前就会启动。这就是安全规则能够安全有效地拒绝访问的方式,而不必回滚已经发生的任何写入。

您引用的文档表明,在记录整个事务的状态(在内存中的某种“暂存”环境中)之后,但在事务实际更改数据库之前,getAfter对于检查数据库的内容非常有用,可见大家。这与get不同,因为get只在事务最终提交之前查看数据库的实际内容。简而言之,getAfter然后使用整个事务或批处理的整个分阶段写入,而get使用数据库的实际现有内容。

如果getAfter适用于您的情况,那么您绝不必使用get

当您需要检查可能已在事务或批处理中更改的其他文档时,getAfter非常有用,并且仍有机会通过使规则失败来拒绝整个事务或批处理。因此,例如,如果在单个事务中编写的两个文档必须具有一些共同的字段值才能保持一致,则需要使用getAfter来验证两者之间的相等性。 get在这里没有帮助,因为它对交易中尚未编写的其他文件一无所知。

另一方面,如果您的规则需要检查事务中的文档是否未更改现有文档中的字段(这不是当前正在检查的文档),则需要使用get来获取该值,而不是交易所写的。

© www.soinside.com 2019 - 2024. All rights reserved.