0
votes

I've seen this question a zillion times, always answered by the extremely helpful @doug-stevenson ... but for the life of me after carefully reading through these I still can't see what i'm doing wrong.

Query (swift): DB.collectionGroup("sessions").whereField("email", arrayContains: "[email protected]")

I tried just hard-setting a value in the rules like this (see second rule):

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /tenants-v1/{tenantId}/{doc=**} {
        allow read: if request.auth != null
                  && get(/databases/$(database)/documents/tenants-v1/$(tenantId)).data.uid == request.auth.uid;
    }

    match /{path=**}/sessions/{session} {
      allow read: if request.auth != null
                     && resource.data.tenantId == 'timsolo';
    }

    match /{document=**} {
      allow read, write: if false;
    }
  }
}

... and made sure /tenants-v1/timsolo/galleries/Dzim0sqH9ewwWY7C43oo/sessions/D6Ffo9VYWfcEgXaLVKJb contains a field tenantId with value string timsolo.

That did not work as expected: the query returns Missing or insufficient permissions.

Sanity test: taking out the last line of the second rule above (so it just allows all authenticated requests) causes this collectionGroup query to work as expected.

What's going on, why can't I check resource.data ?

End desire is to check auth.token.tenantIds, a custom-claim on the token, against the value in the data. I'd prefer to check against resource['__name__'][4] because that's the value I actually care about, but that doesn't work either. Anyways let's get the basic working first...

1
Can you share the entire code for your security rules. Also what is the exact query used for testing your rule? (Not DB.collectionGroup("sessions").whereField("email", arrayContains: "[email protected]") I guess).Renaud Tarnec
@RenaudTarnec OK I updated the question to show all the rules. No, that is indeed the entire query used for testing... there's a getDocuments on the end to execute the query, maybe you mean that part is missing in the above?xaphod

1 Answers

0
votes

The problem seems indeed to come from this part:

... && get(/databases/$(database)/documents/tenants-v1/$(tenantId)).data.uid == request.auth.uid;

If you try to simply query for the /tenants-v1/timsolo/galleries/Dzim0sqH9ewwWY7C43oo/sessions/D6Ffo9VYWfcEgXaLVKJb document, you need to have an uid field in the /tenants-v1/timsolo/ document with the value corresponding to the uid of the authenticated user.


Note that you can easily detect that by using the "Rules Playground", see the doc for more info.