Recursive wildcards in Firestore security rules do not work properly

I have a data structure like this (compilations and documents, not JSON, of course, but you get this idea):

{
   users: {
      user1:{
         name: Alice,
         groups: {
            groupA:{subbed:true},
            groupB:{subbed:true}
         }
      },
      user2:{
         name: Bob,
         groups: {
            groupC:{subbed:true},
            groupD:{subbed:true}
         }
      }
   }
}

These are mainly registered user identifiers and group identifiers to which each user is subscribed. I wanted to write a security rule allowing access to user profiles and subcategories only if they are the current auth user and, based on my reading of the documents, I thought that the wildcard would achieve this ...

match /users/{user=**}{
   allow read,write: if user == request.auth.uid;
}

In doing so, I can read the document perfectly user, but I get a permission error when trying to read a subcategory groups. I can make it work by explicitly matching the subtask ...

match /appUsers/{user}{
   allow read,write: if user == request.auth.uid;

   match /groups/{group}{
      allow read,write: if user == request.auth.uid;
   }
}

... , ? , {user=**} user , - .. .. Ad infinitum ( ) , , .

Firestore, :)

+7
3

Firebase , . , , ( ), .

.

  1. /users/{userId}
  2. , /users/{userId}.

    service cloud.firestore { match/databases/{database}/documents { match/users/{userId} { allow read, write: if request.auth.uid == userId; } match/users/{userId}/{document=**} { allow read, write: if request.auth.uid == userId; } } }

. .

+7

, , , =**, , == request.auth.uid, ():

( users/aHt3vGtyggD5fgGHJ)

user = 'aHt3vGtyggD5fgGHJ'
user == request.auth.uid? Yes
allow access

( users/aHt3vGtyggD5fgGHJ/groups/h1s5GDS53)

user = 'aHt3vGtyggD5fgGHJ/groups/h1s5GDS53'
user == request.auth.uid? No
deny access

: , , , :

function checkAuthorization(usr) {
   return usr.split('/')[0] == request.auth.uid;
}
match /users/{user=**}{
   allow read,write: if checkAuthorization(user);
}

( match /databases/{database}/documents, )

, :)

+4

2.

match/cities/{city}/{document=**} towns match/cities/{city}/{document=**} , .

rules_version = '2'; 2, rules_version = '2'; .

( 2).

, :

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{city}/{document=**} {
      allow read, write: if <condition>;
    }
  }
}
0
source

Source: https://habr.com/ru/post/1688683/


All Articles