resource.data.size()如何在Firestore规则(被计算在内)中工作?

时间:2018-09-09 13:44:29

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

TLDR :在将一些布尔值和嵌套对象写入文档中时,request.resource.data.size()在Firestore规则中的计数是多少?不确定文档中“ 条目在地图中”(https://firebase.google.com/docs/reference/rules/rules.firestore.Resource#datahttps://firebase.google.com/docs/reference/rules/rules.Map)的含义,并且在规则模拟器中测试时我的假设似乎是错误的(与request.resource.data.keys().size()


较长版本:在Firestore规则中遇到了一个问题,即无法按预期更新数据(尽管在规则模拟器中进行了类似的测试)。缩小问题范围,指出在哪里可以看到检查request.resource.data.size()是否等于某个数字的规则。

将数据传递到Firestore update函数的示例看起来像

 Object {
   "parentObj": Object {
     "nestedObj": Object {
       "key1": Timestamp {
         "nanoseconds": 998000000,
         "seconds": 1536498767,
       },
     },
   },
   "otherKey": true,
 }

其中时间戳是通过firebase.firestore.Timestamp.now()生成的。 这在规则模拟器中似乎可以正常工作,但在执行时对于实际数据却不能

let obj = {}
obj.otherKey = true
// since want to set object key name dynamically as nestedObj value,
// see https://stackoverflow.com/a/47296152/8236733
obj.parentObj = {} // needed for adding nested dynamic keys
obj.parentObj[nestedObj] = {
    key1: fb.firestore.Timestamp.now()
}

firebase.firestore.collection('mycollection')
.doc('mydoc')
.update(obj)

在其他一些规则中,我使用了规则request.resource.data.size() == 2,这似乎是导致权限被拒绝错误的规则(因为注释掉了这些规则后,事情再次起作用了)。会认为由于对象是通过2个(顶级)键传递的,因此request.resource.data.size() = 2,但是显然不是这种情况(传递的对象中键的总数也不是)(类似request.resource.data.keys().size()有问题)。因此,对于一个简短的问题有一个很好的例子。如果有人可以帮我弄清楚这里出了什么问题,那将非常有帮助。

2 个答案:

答案 0 :(得分:6)

大约一个月前,我在上一次与Firebase支持的通信中-request.resource.data.size()和基于时间戳的查询安全规则存在问题。

还告诉我request.resource.data.size()是成功写入后文档的大小。因此,如果您要使用4个键将另外2个键写入文档,则应检查的值是6,而不是2。

说了这么多-我对request.resource.data.size()以及本文档中似乎使用的request.resource.size()之类的其他替代品仍然有疑问 https://firebase.google.com/docs/firestore/solutions/role-based-access

我的安全规则中还有一些地方似乎可行。我个人不知道为什么会这样。

答案 1 :(得分:0)

经过数小时的努力,现在我知道Firebase上的文档很清楚:“ request.resource变量包含文档的将来状态”。因此,使用所有字段,不仅是要发送的字段。 https://firebase.google.com/docs/firestore/security/rules-conditions#data_validation

但是实际上还有另一种方法可以只计算通过request.writeFields.size()发送的字段数。属性writeFields是一个包含所有传入字段的表。

当心:不建议使用writeFields,它可能随时停止工作,但是我没有找到任何替代方法。

编辑:writeFields显然在模拟器中不再起作用...