skip to Main Content

I recently run into this limit. After some optimisations I was able to get within the limit but now I’ve got several questions.

  1. 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?

  1. 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

  1. I guess there is no easy way to know the current level of expression evaluations for a specific request?

  2. is there any documentation available on how this process of expression evaluation works in more detail?

2

Answers


  1. Chosen as BEST ANSWER

    Figured for [...].hasAny([...])

    1. complexity here is linear and is calculated like this:

    length(list1) + length(list2) + 3 (1 for list1 result, 1 for list2 result and one for hasAny)

    Example: [1, 2, 3, 4].hasAny([4, 5, 6, 7, 8]) => 12 expressions (4 + 5 + 1 + 1 + 1 = 12)

    1. The number of expressions doesn't depend on the values of the elements of the lists.

    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 to true (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:

    rules_version = '2';
    service cloud.firestore {
        match /databases/{database}/documents {
    
    
            match /{document=**}/mycollection/{docId} {
              allow read: if hugeListRule();
            }
    
    //====== helper functions start ==========
    
        function hugeListRule(){
           return [...10...].hasAny([...1000...])
        }
        
    }
    

    Playground url (change project_id to yours):

    https://console.firebase.google.com/u/0/project/{project_id}/firestore/rules


  2. 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:

    1. 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 mark
    2. allow read, write: if condition1 || condition2 && condition3. This may evaluate as 1 (if condition1 is true), 2 (if condition1 and condition2 are false) or 3 (if condition1 is false and condition12 is true) expressions
    3. Unfortunatly not, you only know when you have hit the 1000 mark
    4. No official doc, just hints of firebaser here on SO for instance 🙁

    Here 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search