firebase - Firestore,安全规则,如何限制地图字段内容数组的大小
问题描述
我在 Firestore 中有这个结构
{
"fields": ...
"fields": ...
"arrayFields":[
<index 0>
"field A": ...
"field B": ...
"field C": ...
<index 1>
"field A": ...
"field B": ...
"field C": ...
<index 2>
"field A": ...
"field B": ...
"field C": ...
]
}
它似乎在下面不起作用
if request.resource.data.arrayFields['field A'].size() < 12;
我想限制地图字段数组的大小
解决方案
Cloud Firestore 安全规则将数组称为List
,因此我将在此处使用该术语。
以下规则使用自定义函数来描述我们正在执行的检查:
function doesFieldOfIndexInListHaveSizeLessThan(field, index, list, size) {
return index + 1 <= list.size() // is index in list's bounds
&& field in list[index] // does the target element have the named field
&& list[index][field].size() < size; // does the value of the element's field
// have a size less than the given value
}
doesFieldOfIndexInListHaveSizeLessThan('field A', 0, request.resource.data.arrayFields, 10);
要对多个索引执行此检查,您必须单独编码每个索引,因为安全规则无法迭代。
doesFieldOfIndexInListHaveSizeLessThan('field A', 0, request.resource.data.arrayFields, 10)
&& doesFieldOfIndexInListHaveSizeLessThan('field A', 1, request.resource.data.arrayFields, 10)
&& doesFieldOfIndexInListHaveSizeLessThan('field A', 2, request.resource.data.arrayFields, 10)
&& // and so on...
您可以将它放在另一个函数中,以使条件(而不是实现)更具可读性。在开发自定义函数时,您需要记住它们可以调用其他函数但不能递归,并且它们的总调用堆栈深度限制为 10。将上述规则重写为函数将给出:
function doesFieldInListElementsHaveSizeLessThan(field, list, size, startingOffset, elementsToCheck) {
return (elementsToCheck > 0 && elementsToCheck <= 10) // elementsToCheck must be between 0 & 10, otherwise fail early
&& startingOffset >= 0 // if starting index is negative, fail early
&& doesFieldOfIndexInListHaveSizeLessThan(field, startingOffset, list, size)
&& (elementsToCheck > 1 && doesFieldOfIndexInListHaveSizeLessThan(field, startingOffset + 1, list, size)
&& (elementsToCheck > 2 && doesFieldOfIndexInListHaveSizeLessThan(field, startingOffset + 2, list, size)
&& (elementsToCheck > 3 && doesFieldOfIndexInListHaveSizeLessThan(field, startingOffset + 3, list, size)
&& (elementsToCheck > 4 && doesFieldOfIndexInListHaveSizeLessThan(field, startingOffset + 4, list, size)
&& (elementsToCheck > 5 && doesFieldOfIndexInListHaveSizeLessThan(field, startingOffset + 5, list, size)
&& (elementsToCheck > 6 && doesFieldOfIndexInListHaveSizeLessThan(field, startingOffset + 6, list, size)
&& (elementsToCheck > 7 && doesFieldOfIndexInListHaveSizeLessThan(field, startingOffset + 7, list, size)
&& (elementsToCheck > 8 && doesFieldOfIndexInListHaveSizeLessThan(field, startingOffset + 8, list, size)
&& (elementsToCheck > 9 && doesFieldOfIndexInListHaveSizeLessThan(field, startingOffset + 9, list, size)
}
// checks first 10 elements to see if their 'field A' is less than 10 characters long
doesFieldInListElementsHaveSizeLessThan('field A', request.resource.data.arrayFields, 10, 0, 10)
// checks next 5 elements to see if their 'field A' is less than 10 characters long
&& doesFieldInListElementsHaveSizeLessThan('field A', request.resource.data.arrayFields, 10, 10, 5);
注意:如果您希望您的数组非常大,请使用 Firestore 集合而不是文档中的数组。这将大大简化您的安全规则。
推荐阅读
- javascript - Rails - 后退按钮复制元素
- android - 如何使用开关创建指纹锁以启用/禁用锁定
- render - 删除对象渲染
- flutter - 从互联网获取数据并推送到数组颤振
- kotlin - 将列表动态添加到 Kotlin 中的列表中
- amazon-web-services - TCP 连接锁定在“CLOSE_WAIT”状态,IIS 应用程序在 AWS 服务器上进行 Kerberos 身份验证(Windows 服务器 2016 标准)
- c++ - 对向量进行排序时的奇怪行为
- apache-spark - Pyspark Fpgrowth - 是否可以只返回关闭的频繁项集?
- jquery - 几个拥有大型 JQuery 自动完成数据集的用户降低了整个 Ruby on Rails 应用程序的速度
- azure - ESP32 的 C2D 消息