Search code examples
firebasegoogle-cloud-platformgoogle-cloud-firestorefirebase-security

What is the correct Firestore security Rule for the following scenario?


I have a firestore db like this

  • users
    • {userId}
      • boards
        • {boardId}
          • Board Data

I have firestore security rules setup like this.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read: if request.auth != null;
    }
    match /users/{userId}/{document=**} {
      allow read, create, update, delete: if request.auth != null && request.auth.uid == userId ;
    }
  }
}

How should I setup the rules that-

  • Users can only access their own data.
  • No one can access the root users collection

Solution

  • There is an overlapping match statement in your rules, since you use match /{document=**} which maps to ALL documents in your database (see the doc).

    So, since:

    1. In the case where multiple allow expressions match a request, the access is allowed if any of the conditions is true, and
    2. For the match /{document=**} statement your rule is allow read: if request.auth != null;, then

    every authenticated user can read any user document (you don't restrict on the uid as you do for the users collection. And actually you cannot do so, since match /{document=**} does not specifically target the users collection).

    The best is to remove this block and just keep the following block.

    match /users/{userId}/{document=**} {
      allow read, create, update, delete: if request.auth != null && request.auth.uid == userId ;
    }
    

    And if you need to grant read access to other collections, use a rule for each collection, instead of using the wildcard approach.


    PS: You may double check if you really need to do match /users/{userId}/{document=**}, which grants access to all subcollections of the users docs. You may just need to do match /users/{userId}.