I recently run into this limit. After some optimisations I was able to get within the limit but now I’ve got several questions.
- Is that true that the number of expressions for the particular request is constant, i.e. it doesn’t depend on the data involved?
For example if I use [...].hasAny([...])
– is that always 1/constant expressions or does it depend on the size of the lists involved?
What I’m trying to figure out is in regard to 1000 expressions, if any particular rule successfully executes in unit tests, is it safe to assume that the same rule will never hit this limit of 1000 in production or that would also depend on user data?
- Is that true that the evaluation of expressions always take into account all possible routes and the number of expressions doesn’t depend on the result of any conditions.
Example: consider the following rule
allow read, write: if condition1 || condition2 && condition3
In this case this will always be counted as 3 expressions (or is it?) despite if condition1
was true or false
-
I guess there is no easy way to know the current level of expression evaluations for a specific request?
-
is there any documentation available on how this process of expression evaluation works in more detail?
2
Answers
Figured for
[...].hasAny([...])
length(list1)
+length(list2)
+3
(1 forlist1
result, 1 forlist2
result and one forhasAny
)Example:
[1, 2, 3, 4].hasAny([4, 5, 6, 7, 8])
=> 12 expressions (4 + 5 + 1 + 1 + 1 = 12)I.e.
[1, 2, 3, 4].hasAny([4, 5, 6, 7, 8])
and[4, 4, 4, 4].hasAny([4, 4, 4, 4, 4])
both give 12 expressions, even though in the second case it's enough to have just one comparison to evaluate the whole expression totrue
(plus 3 more expressions as mentioned above).I guess this has to do with the linear algorithm used internally for this.
Note on the underlying tests:
My tests involved hardcoded list like
[..10..].hasAny[...1000...]
that I first generated in javascript and outputted it in console. Then manipulated the list in playground to account for different scenarios.I was using the following playground snippet:
Playground url (change project_id to yours):
https://console.firebase.google.com/u/0/project/{project_id}/firestore/rules
The number of expressions in a rule depends on the data involved as it is equal to the number of expressions actually evaluated.
Your could have a rules with 10000 expressions but if all evaluation paths are under 500 expressions each then you are fine.
Regarding your two example:
somevariable.hasAny(["a","b", "c", "d"])
: this is 7 expressions to me,somevariable
,hasAny
and one for each element of the list + 1 for the list itself. To test this you could write a rule calling a function with such a test, put 20 elements in the list and call the function many times until you hit the 1000 markallow read, write: if condition1 || condition2 && condition3
. This may evaluate as 1 (ifcondition1
is true), 2 (ifcondition1
andcondition2
are false) or 3 (ifcondition1
is false andcondition12
is true) expressionsHere are also two previous answers that may help: Expressions in firebase firestore security rule and Firestore rules: maximum of 1000 expressions to evaluate has been reached.