我想知道是否有可能为我的以下代码避免Firestore安全规则的函数调用深度限制。
什么算作功能?只是我自己创建的还是size()
之类的东西?
function isValidItem(data, item) {
return
( // Person
data.items[item].keys().hasAll(['image','type','name','job','age','party','experience'])
&& data.items[item].image.size() >= 1 && data.items[item].image.size() <= 200
&& data.items[item].type.size() >= 5 && data.items[item].type.size() <= 10
&& data.items[item].name.size() >= 1 && data.items[item].name.size() <= 50
&& data.items[item].job.size() >= 1 && data.items[item].job.size() <= 50
&& data.items[item].party.size() >= 1 && data.items[item].party.size() <= 50
&& data.items[item].experience.size() >= 1 && data.items[item].experience.size() <= 50
&& data.items[item].age.matches('^[0-9]+$')
)
||
( // Party
data.items[item].keys().hasAll(['image','type','name','orientation','experience','promi'])
&& data.items[item].image.size() >= 1 && data.items[item].image.size() <= 200
&& data.items[item].type.size() >= 5 && data.items[item].type.size() <= 10
&& data.items[item].name.size() >= 1 && data.items[item].name.size() <= 50
&& data.items[item].orientation.size() >= 1 && data.items[item].orientation.size() <= 50
&& data.items[item].experience.size() >= 1 && data.items[item].experience.size() <= 50
&& data.items[item].promi.size() >= 1 && data.items[item].promi.size() <= 50
);
}
function itemsAreValid(data) {
return data.items.size() >= 1
&& data.items.size() <= 10
&& isValidItem(data, 0)
&& (data.items.size() < 2 || isValidItem(data, 1))
&& (data.items.size() < 3 || isValidItem(data, 2))
&& (data.items.size() < 4 || isValidItem(data, 3))
&& (data.items.size() < 5 || isValidItem(data, 4))
&& (data.items.size() < 6 || isValidItem(data, 5))
&& (data.items.size() < 7 || isValidItem(data, 6))
&& (data.items.size() < 8 || isValidItem(data, 7))
&& (data.items.size() < 9 || isValidItem(data, 8))
&& (data.items.size() < 10 || isValidItem(data, 9));
}
function isValidTitle(data) {
return data.title.size() >= 1
&& data.title.size() <= 200
}
function isAuthed() {
return request.auth.uid != null
&& request.auth.token.email_verified == true;
}
allow create, update:
if isAuthed()
&& request.resource.data.user == request.auth.uid
&& request.resource.data.status == "review"
&& isValidTitle(request.resource.data)
&& itemsAreValid(request.resource.data);
答案 0 :(得分:2)
我与Firebase安全规则小组进行了检查,我们发现您超出的限制几乎可以肯定是允许的表达式总数。现在记录为10,000,但该数字实际上是不正确的。应记录为1,000。这就是为什么当您减少一些规则时,它就可以开始工作的原因。那时您可能进入了1000个限制以下。
您可以采取的改善状况的方法是不必要地停止重复调用函数。例如,您可以只写isValidItem(map, key)
map[key]
然后反复调用isValidItem(value)
不幸的是,目前尚无可用于安全规则的日志或调试信息,因此有时出问题时您需要猜测一下。
我们将修复文档,并在内部进行更多讨论。
答案 1 :(得分:1)
每次调用data()->文档参考。
限制是文档访问,在此调用中data()是问题所在。您通过多次调用数据来引用文档。为了避免这种情况,您可以将data()传递给函数并验证其中的所有内容。
Access call limits
There is a limit on document access calls per rule set evaluation:
10 for single-document requests and query requests.
20 for multi-document reads, transactions, and batched writes. The previous limit of 10 also applies to each operation.
For example, imagine you create a batched write request with 3 write operations and that your security rules use 2 document access calls to validate each write. In this case, each write uses 2 of its 10 access calls and the batched write request uses 6 of its 20 access calls.
Exceeding either limit results in a permission denied error. Some document access calls may be cached, and cached calls do not count towards the limits
https://firebase.google.com/docs/firestore/security/rules-conditions