2

I need a firestore rule that allows access for user ids that are in the users field in a document:

Document 1:
    uid: 13423425,
    ...,
    users: [{uid: 123, email: [email protected]}, {uid: 456, email: [email protected]}]

User 123 should be able to access this field, but a user 999 would not be able to access this document. How do I write a firestore rule that allows me to check whether a given user id is in the users field? I tried using the IN operator but it doesn't work in this case since it is an array of maps (not an array of strings or numbers). Essentially I'm trying to write a rule like this (using a map):

function isAllowed(sometableId) {
    return request.auth.uid != null
    && request.auth.uid in get(/databases/$(database)/documents/sometable/$(sometableId)).data.users.map(user => user.uid);
}


match /sometable/{sometableId} {
  allow create: if request.auth.uid != null;
  allow read, write: if isAllowed(sometableId);
}

1 Answer 1

2

What you're trying to do isn't possible with your document structure. Rules currently provide no way to iterate an array or perform a map-like operation. Consider a different structure instead that puts the values you want to filter as the array values (yes, you will be duplicating data from users into a new field):

Document 1:
    uid: 13423425,
    ...,
    users: ...,
    fullAccess: ['123', '456']

Now your rule can be written like this:

match /sometable/{sometableId} {
  allow create: if request.auth.uid != null;
  allow read, write: if request.auth.uid in resource.data.fullAccess;
}

You could also solve this using a map with uid values for keys, and nested properties containing a boolean values that indicates read/write access.

Sign up to request clarification or add additional context in comments.

3 Comments

How would your second suggestion work? Would I do the following: users: {123: '[email protected]', 456: '[email protected]'}] in this case how would the rule look
You still need a boolean to check in the document data.
@DougStevenson can you elaborate on the need for the boolean when going the route of a map of uid keys? Could it be enough that if the key 123 is found in the users map, then user 123 is granted access?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.