Search code examples
firebasegoogle-cloud-firestorefirebase-security

How to write a firestore rule to query another collection, where value is equal to some value


The roles collection have a field of uid that references a real user id(request.auth.id) and a roles field that contains an array of role(s).

function hasRoles(rsc, roles) {
    return (rsc in roles);
}

// The rule

allow write, create: if hasRoles(get(/databases/$(database)/documents/roles).data.uid == request.auth.uid, ['super_admin']);

enter image description here


Solution

  • Preamble: The following answer makes the assumption that the ID of the ‘role‘ document correspond to the user’s UID, which is not exactly your data model. You’ll need to slightly adapt your data model.

    To get the doc you need to do:

    get(/databases/$(database)/documents/roles/$(request.auth.uid))

    Then you want to get the value of the ‘role‘ field:

    get(/databases/$(database)/documents/roles/$(request.auth.uid)).data.role

    Then you need to use the in operator of list, to check if the super_admin string is in the array field role:

    "super_admin" in get(/databases/$(database)/documents/roles/$(request.auth.uid)).data.role

    You can also test more than one role at a time with List#hasAll():

    get(/databases/$(database)/documents/roles/$(request.auth.uid)).data.role.hasAll(["editor", "publisher"])

    These will return true or false (note that I haven’t tested it, being commuting and writing on a smartphone, so there may be some fine tuning to be done! :-))