Firebase Firestore, can you have multiple update rules for a collection

Viewed 1117

I've inherited a project and I'm having a permissions problem when trying to update a property on a particular collection.

Looking at the Firestore rules that have been setup, it lists multiple update rules and I wondered, is this allowed? I've tried to use the rules playground in Firebase, but I'm getting an error telling me that for one of the rules the name property isn't defined, which is correct as I'm not updating the name property. Would Firebase then skip that rule and move onto the next one to see if it applies?

For reference, here are the rules for the collection;

match /teams/{id} {
      allow read:   if request.auth.uid != null
                    && request.auth.uid in resource.data.members;

      allow read: if isAdmin();

      allow create: if true;

      allow update: if request.auth.uid != null
                    && request.resource.data.keys().hasOnly(['name', 'owners', 'members'])
                    && request.resource.data.name is string
                    && request.resource.data.name.size() >= 1
                    // ToDo: Validate values in list
                    && request.resource.data.owners is list
                    && request.resource.data.owners.size() >= 1
                    // ToDo: Validate values in list
                    && request.resource.data.members is list
                    && request.resource.data.members.size() >= 1
                    && request.auth.uid in resource.data.owners;

      allow update: if request.auth.uid != null
                    && request.resource.data.keys().hasOnly(['name', 'owners', 'members'])
                    && request.resource.data.name == resource.data.name
                    && request.resource.data.owners == resource.data.owners
                    // ToDo: Validate values in list
                    && request.resource.data.members is list
                    && request.resource.data.members.hasAll(resource.data.members)
                    && exists(path('/databases/' + database + '/documents/subinvites/' + request.auth.uid + id));

      allow update: if isAdmin();
    }

I'm trying to update the members property on the team collection like this;

Firebase.firestore()
    .collection("teams")
    .doc(teamId)
    .update({
        members: Firebase.firestore.FieldValue.arrayUnion(userId),
    });

However, looking at the rules and the code above, this surely won't work as both of the update roles seems to be requiring the request to contain name, owners and members, where as the request only passes members. This also means that the condition request.resource.data.name == resource.data.name can't possible be true if the name property

1 Answers

it lists multiple update rules and I wondered, is this allowed?

Yes, you can have multiple rules for a particular access method.

Would Firebase then skip that rule and move onto the next one to see if it applies?

No rules are skipped. If you have multiple rules, it will compute the logical OR of each one. So, if any of the rules allows update, then that access is granted.

that the condition request.resource.data.name == resource.data.name can't possible be true if the name property

Not necessarily. If the document had a name field prior to the update, it will have that value here. request.resource.data contains the entire contents of the new document being written, not just the fields that were specified in the update. But if the field doesn't already exist, and you don't provide one in the update, then the rules will reject the update.

Related