6
votes

I want to implement role based restrictions in my application. I have the user role information in one collection documents. Now I want to write rules to restrict different Write, Update operation on other collections of the database.

Since I am using Firestore database with React-Native I only pass the respective collection's document info while inserting/updating. So how can I pass the user's role information along with this so that my rule gets authenticated and that data doesn't go into other collection.

One example depicting above scenario:

/collection1/document1
{
   prop1: value1,
   prop2: value2,
   role: "WRITE"
}

/collection1/document2
{
   prop1: value1,
   prop2: value2,
   role: "READ"
}

Now consider that current logged in user is document2.

I have another collection:

/collection2/doc1
{
   userRef: document1, //this is id of document1 from collection1
   ...
}

I want to configure firestore rule for collection2 that if request has come from user with role="WRITE" then only allow it to isert/update documents.

Have read many articles and ways but any of them does not satisfy this use-case.

Any help would be appreciated.

1
"Now consider that current logged in user is document2". I'm having a hard time understanding what this means. How does the logged in user relate to the document? It might help if you give your collections and documents meaningful names for the use-case you're asking about.Frank van Puffelen
@FrankvanPuffelen Consider that logged in user is being represented by document2 which has role of "READ". I want to make sure that this user only gets to read the documents within my app. Now your doubt could be why is user represented by document2? Here i would like to say that consider this user belongs to one client for which it has READ access. The same user can also have access to second client for which it has WRITE access. Hence storing role information in firestore /users collection doesn't work. Hope this clears your doubt.Hriday Modi
It's a little hard to follow the question but I would advise watching this video, even though its for angular, it's still firebase/firestore and it tackles how to conceptually introduce role-based auth into a firestore application. youtube.com/watch?v=1PEdd2rtG30Isuru Fonseka
@IsuruFonseka In video they are using firestore's "/users" collection to store Role information. While as mention above in my comment, my use-case is different. In my case user can have different role on different client, i.e. user1 can have ADMIN access on client1 while same user can have READ access on client2. Hence here Role is based on User+Client and not only on User, so solution provided in video won't work.Hriday Modi

1 Answers

3
votes

To make the rules easier to read, you can create a function that gets the user role, then use in the conditions. This is how the firestore.rules file would look like :

service cloud.firestore {
  match /databases/{database}/documents {
    match /collection2/{doc} {
     allow read: if getUserRole() === 'READ' || getUserRole() === 'WRITE';
     allow create: if getUserRole() === 'WRITE';
     allow update: if getUserRole() === 'WRITE';
    }
    function getUserRole() {
        return get(/databases/$(database)/documents/collection1/$(request.auth.uid)).data.role;
    }
  }
}