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

Create variable to reuse in firestore rules


In a complex product, you often has to use the same rule conditions, for example if a user is admin:

match /games/{game} {
  allow read: if true;
  allow write: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true
}
match /locations/{location} {
  allow read: if true;
  allow write: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true
}

Is there a way to store the condition inside a variable to reuse it (instead of write it every time)? For example:

const isAdmin = request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;    

match /games/{game} {
  allow read: if true;
  allow write: if isAdmin
}
match /locations/{location} {
  allow read: if true;
  allow write: if isAdmin
}

I have no idea what's the language behind the firestore rules and what kind of assets I am able to use.


Solution

  • Yes, you can use Custom Functions, as explained in the doc.

    In your case it would be something along the following lines (untested):

    function isAdmin() {
      return request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;    
    }
    match /games/{game} {
      allow read: if true;
      allow write: if isAdmin();
    }
    match /locations/{location} {
      allow read: if true;
      allow write: if isAdmin();
    }
    

    Note that the position of a function within the Security Rule "hierarchy" is important. Have a look at this official video for more details.