0
votes

I have Firebase Database data of the following type:

{ sales: 
    { -Axyz: {shop_id: 1, name: item1},
      -BqwW: {shop_id: 2, name: item2},
      -Cwer: {shop_id: 1, name: item3}
    }
}

I'm using auth token claims to store access levels and ids. I'd like for admin to have access to all records and to shop owner to have access only to their records.

I have the following database rules - admin users have access to all records and shop users have access to their own records:

{
"rules": {
    "sales": {
        ".read": "auth.token.admin === true"
        "$key": {
            ".read": "auth.token.shop === true && data.child('shop_id').val() === auth.token.shop_id"
        }
    } 
} }

Ideally, I'd like to query /sales/ table and get a list of relevant records - all records for admin users and some for shop users.

        firebase.database().ref('sales').on('value', ....

Is it possible to implement this way?

Thank you!

1
Can you edit the question to include the code that tries to read the data and is failing? - Frank van Puffelen
Hi, thanks, I've now edited Q to better explain what I'm trying to achieve. - xims
Your "sales": { ".read": "auth.token.admin === true" will gives read access to users with an admin claim that is true. If such a user runs your code firebase.database().ref('sales').on('value', the read will be allowed. If this read is rejected for you, the user doesn't have the correct claim - Frank van Puffelen
so is it possible for shop users to get a list of all 'their' records from /sales/? - xims
While admins can read /sales, no other users can read from there. You might expect Firebase to automatically filter child nodes that you have access to, but that is unfortunately not the case. Security rules don't automatically filter data (see previous questions about this). So while each user can access each sale node for their shop, they can't read /sales to get a list of them. Query based rules might work, but I'm not sure here - Frank van Puffelen

1 Answers

1
votes

Thanks for the discussion in comments, it's now working for me.

I've used Query-based Rules described at https://firebase.google.com/docs/database/security/securing-data#query-based_rules

firebase.database().ref('sales') 
    .orderByChild('shop_id').equalTo(user.claims.shop_id) 
    .on('value' ...

returns just a list of values that this user allowed to see