Firestore Security Rules - Recursive wildcards strange behavior in rules version 2

Viewed 31

I have the following Firestore rules:

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /threads/{userId}/userThreads/{threadId} {
      allow get: if isSignedIn();
      allow list: if isSignedIn() && isQueryLimitRespected(10);
      allow write: if false;

      match /comments/{document=**} {
        allow get: if isSignedIn();
        allow list: if isSignedIn() && isQueryLimitRespected(5);
        allow write: if false;
      }

      match /likes/{document=**} {
        allow get: if isSignedIn();
        allow list: if isSignedIn() && isQueryLimitRespected(15);
        allow write: if false;
      }
    }
  }
}

And, for some reason (I suppose this is the expected behavior), I cannot make queries of threads if the limit is greater than 5.

My problem is that each comment can have likes and replies too...

So, I have thought to fix this issue as follows:

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /threads/{userId}/userThreads/{threadId} {
      allow get: if isSignedIn();
      allow list: if isSignedIn() && isQueryLimitRespected(10);
      allow write: if false;

      match /comments/{commentId} {
        allow get: if isSignedIn();
        allow list: if isSignedIn() && isQueryLimitRespected(5);
        allow write: if false;

        match /likes/{likeId} {
          allow get: if isSignedIn();
          allow list: if isSignedIn() && isQueryLimitRespected(15);
          allow write: if false;
        }

        match /comments/{commentId} {
          allow get: if isSignedIn();
          allow list: if isSignedIn() && isQueryLimitRespected(5);
          allow write: if false;
        }
      }

      match /likes/{likeId} {
        allow get: if isSignedIn();
        allow list: if isSignedIn() && isQueryLimitRespected(15);
        allow write: if false;
      }
    }
  }
}

As you can see, I avoid using recursive wildcards in the second version of the rules in order to solve the problem.

But... the rules now have a few more lines... is this the correct way to handle this situations? Any refactoring for the rules?


Update

In the docs, it is stated that:

In version 2 of the security rules, recursive wildcards match zero or more path items. match /cities/{city}/{document=**} matches documents in any subcollections as well as documents in the cities collection.

But what about this other use of the recursive wildcards?

match /{path=**}/cities/{city}/{landmark}

Will these refactored rules behave the same for a static NoSQL model?

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /threads/{userId}/userThreads/{threadId} {
      allow get: if isSignedIn();
      allow list: if isSignedIn() && isQueryLimitRespected(10);
      allow write: if false;

      match /{path=**}/likes/{likeId} {
        allow get: if isSignedIn();
        allow list: if isSignedIn() && isQueryLimitRespected(15);
        allow write: if false;
      }

      match /{path=**}/comments/{commentId} {
        allow get: if isSignedIn();
        allow list: if isSignedIn() && isQueryLimitRespected(5);
        allow write: if false;
      }
    }
  }
}
0 Answers
Related