NLam
NLam

Reputation: 557

Firestore rule on condition from a different collection

I have a Firestore db with two collections: users and tournaments. The users have a 'participant' role and an 'admin' role and are indicated by 'isParticipant' and 'isAdmin' booleans in the user document:

/users/{userId}:
  isParticipant: true
  isAdmin: true

I have access rules set up for these collections like so:

service cloud.firestore {
  match /databases/{database}/documents {
     match /users/{userId} {
      allow create, read;
      allow update: if request.auth.uid == userId;
    }
     match /tournaments/{tournamentId} {
      allow create, read, update: if request.auth.uid != null;
    }
  }
}

However, what I really want to do is restrict the creation of a tournament to a user that is of an 'admin' role. I am already doing this in code, but would like the added security of a db rule to prevent anyone but an admin user from creating a tournament.

Is there a way to reference the data element of a different collection within the rules syntax? Something like:

     match /tournaments/{tournamentId} {
      allow create: if resources.users.userId.isAdmin == true;
    }

?

Thanks in advance.

Upvotes: 2

Views: 2947

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598740

You can access the data in a different collection by using the get function:

 // Allow the user to delete cities if their user document has the
 // 'admin' field set to 'true'
 allow delete: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true

For more information on this, see access other documents in the Firebase documentation, which is where I got the above example from.

One thing to note is that this requires an additional document read. If you'd store the fact that a user is an admin inside their profile as a custom claim, you could access it from request.auth without needing an extra read. E.g.

allow delete: if request.auth.token.admin == true

For more on this, see control access with custom claims and accessing the user token in the documentation.

Upvotes: 14

Related Questions