在 Cloud Firestore 规则中 - 如何检查密钥是不是为空
Posted
技术标签:
【中文标题】在 Cloud Firestore 规则中 - 如何检查密钥是不是为空【英文标题】:In Cloud Firestore rules - How do I check if a key is null在 Cloud Firestore 规则中 - 如何检查密钥是否为空 【发布时间】:2018-03-19 17:38:41 【问题描述】:在 Cloud Firestore 规则中 - 我有一个名为 task
的文档,我想查看某些数据(assignee
字段)是否为空/不存在。
我试过了:
resource.data.assignee == null
- 不起作用(错误)
!resource.data.hasAll(['assignee'])
- 不起作用(错误)
从文档中 - 它指出这确实会产生错误:
// Error, key doesn't exist
allow read: if resource.data.nonExistentKey == 'value';
【问题讨论】:
这里是完整的规则文件 - github.com/Metaburn/doocrate/blob/master/firestore.rules 据我所知resource
是一个文档,因为我使用的是 match /tasks/anyTask
来自关于资源的 firebase 文档 - firebase.google.com/docs/firestore/reference/security/…
我不需要检查文件——我知道文件就在那里。我想检查该文档中的字段。所以对于/tasks/my-task
- tasks
是集合。 my-task
是文档。里面有一个字段assignee
- 我想看看它是否为空,我不能
有一个resource.data.keys()
函数,尝试使用hasAll(['assignee'])
代替。
也许你会遇到!resource.data.keys().hasAll(['assignee'])
的运气
繁荣@Callam 你明白了。
【参考方案1】:
阅读 Firestore 安全规则文档here 的列表比较,我们可以看到,如果列表中存在所有值,hasAll
返回 true。
// Allow read if one list has all items in the other list
allow read: if ['username', 'age'].hasAll(['username', 'age']);
request.resource.data
是一个包含字段和值的映射。为了使用hasAll
,我们必须首先将键作为值列表获取,如here所示。
!resource.data.keys().hasAll(['assignee'])
【讨论】:
!('asignee' in resource.data.keys())
也应该工作吗?另一件需要注意的是,来自规则文档:“资源中存在的请求中未提供的字段被添加到 request.resource.data
。规则可以通过比较 request.resource.data.foo
和 resource.data.foo
来测试字段是否被修改。 resource
中的每个字段也将出现在 request.resource
中,即使它没有在写入请求中提交。”,因此有时可能存在密钥并且您不希望它...跨度>
@menehune23 确实如此,而且很难判断客户端应用程序是否不包含一个字段,如果它可能已经存在于资源中。此外,规则模拟器不支持将资源复制到请求字段,因此您可以在模拟器中构建一个可以工作但不会工作的更新一个真正的应用程序......非常令人沮丧。【参考方案2】:
查看文档 - https://firebase.google.com/docs/reference/rules/rules.Map
k in x - Check if key k exists in map x
所以这应该可以工作(没有键())
!('assignee' in resource.data)
【讨论】:
【参考方案3】:如果您想确保某个键为空,您需要检查该键是否不是资源键属性的一部分:!resource.data.keys().hasAny(['assignee'])
您也可以使用hasAll
或hasOnly
。更多信息here
【讨论】:
以上是关于在 Cloud Firestore 规则中 - 如何检查密钥是不是为空的主要内容,如果未能解决你的问题,请参考以下文章
在 Cloud Firestore 中如何制作一个,只创建一次安全规则
在 Cloud Firestore 规则中,request.auth.uid 似乎始终为空