10

I'm currently trying to build small app on firebase as an evaluation of it. It looks interesting and super productive, but I have one problem with firestore rules.

I have one collection (games) with objects looking like this:

{
    "name":String,
    "description":String,
    "owners": 
    {
        "uid": String
        "uid2": String
    }
}

And rules set like this:

service cloud.firestore {
    match /databases/{database}/documents {
        match /games {
            match /{game} {
                allow write: if request.auth != null && request.resource.data.owners[request.auth.uid] == 'ADMIN';
                allow update: if request.auth != null && resource.data.owners[request.auth.uid] == 'ADMIN';
                allow read: if request.auth != null && resource.data.owners[request.auth.uid] == 'ADMIN';
            }
        }
    }
}

While write, update work fine. Read only works for single documents. When I try to read a collection I get access error as if user did not have right to it. The part that makes it not work is

resource.data.owners[request.auth.uid] == 'ADMIN'.

Adding a where("owners."+auth.uid,"==", 'ADMIN') to collection query does not help either.

What am I doing wrong here? Is there a suggested approach in firebase firestore for similar scenario?

EDIT: I tried adding 'get' and 'list' rules like this:

allow list: if request.auth != null;

allow get: if request.auth != null && resource.data.owners[request.auth.uid] == 'ADMIN';

It didn't work as expected. I expected it to allow me to list documents with where but if there is a document that I could not get I expected to get "Missing or insufficient permissions." What I was able to do was to list ALL documents but not read some of them directly (get rule works when trying to fetch single document but not when listing them from a collection).

EDIT 2: Looks like according to @MikeMcDonald my expectation was correct, but it is currently bugged. Waiting for the fix.

EDIT 3: It is now working fine with rules to get and list set in this way:

allow get, list: if request.auth != null && resource.data.owners[request.auth.uid] == 'ADMIN';

Mariusz Zawadzki
  • 479
  • 1
  • 3
  • 13
  • 1
    Note that `write` is a superset of `update`, so your currently `write` rule overwrites the `update`. Change it to `create` and you'll get a little closer to your intended goal. – Mike McDonald Oct 10 '17 at 16:44
  • @MikeMcDonald thanks, I will do that. I also found (after reading a bit closer) that there are two "reads". `get` and `list` later I will try to allow broader list maybe that it something that I need. Thanks! – Mariusz Zawadzki Oct 10 '17 at 16:59
  • 1
    `read` is the umbrella containing `get` and `list`. I've confirmed that the above is a bug--it should work, but we're not handling array members properly here. I'll follow up here once the fix is out. – Mike McDonald Oct 10 '17 at 23:49
  • @MikeMcDonald thanks. For now it is not super critical for me as I'm starting my advanture with firebase but would be nice to be able to do this. Waiting for the good news about the fix :-) – Mariusz Zawadzki Oct 12 '17 at 09:43
  • 1
    I've confirmed the bug is fixed now, so you should be able to use nested properties correctly. – Mike McDonald Nov 27 '17 at 05:17
  • @MikeMcDonald Thank you, just checked and now I'm able to make it working as I want to. – Mariusz Zawadzki Nov 28 '17 at 10:30

1 Answers1

0

I think create and update works because they are part of write and condition 1 covers it.