Search code examples
angularfirebasegoogle-cloud-firestorefirebase-security

How to have some data of a firebase document editable only by user with "admin" status?


In my angular app, I'm using firestore to store the profile of my user. Currently I've something like this:

/profiles/{uid}/:

{
    displayName: "Luigi",//--> Only editable by Luigi
    email: "luigi@mario.com",
    favoriteIceCream: "cookie dough",
    roles: {//--> Not editable by Luigi, only by people with admin role
        admin: true,
        user: true
    }
}

Is there a way to configure my firestore rules to only allow somebody that has the role "admin=true" to update the role object? And then the other informations should be only editable by the user in question(that I know doing)


Solution

  • You can use request.resource object to check which fields are being updates and check if the user is an admin if roles is being updated:

    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        function isAdmin() {
          return get(/databases/$(database)/documents/profiles/$(request.auth.uid)).data.roles.admin == true;
        }
        
        match /profiles/{userId} {
          allow update: if request.auth != null && 
          ((request.resource.data.diff(resource.data).affectedKeys().hasAny(['roles']) && isAdmin()) ||
          ((!request.resource.data.diff(resource.data).affectedKeys().hasAny(['roles']) && request.auth.uid == userId)));
        } 
      }
    }
    

    If roles key is being updated, the above rules will check is the user is admin else if roles key is not being updated, it'll allow the user to update the document.

    You can read more about hasAny() in prevent some fields from being changed section of the documentation.