Oliver
Oliver

Reputation: 667

Firebase realtime database rules for single properties different as for the other properties in same object tree

I try to get my firebase realtime database rules running correct but have a problem with a single property rule.

My firebase object looks like this example

"products": {
        "KUg68BknfYWuEjAKla5": {
          "cat": "Pizzas",
          "likes": 132,
          "item_price": 39.9,
          "item_price_single": 39.9,
          "name": "Mussarela",
          "observation": "",
          "product_id": "-KUg68BknfYWuEjAKla5",
          "product_image": "massapan-mussarela.jpg",
          "quantity": 1
        }

My rules for this object look right now like this

  "products": {
    ".read": true,
    ".write": "root.child('users').child(auth.uid).child('admin').val() == 'user_is_admin'" 
  ".indexOn": ["status", "categoryId"]
},

So basically I allow everybody to read the object but only the admin to write the object. My problem is that the single property "likes" need to be writeable by every authenticated user. Which I would normally do with ".read": "auth != null", but I dont know how to combine them in my rules. Can I set multiple lines with .write? do I need to combine them in one line? I tried all I can think of but without success.

thx in advance

Upvotes: 3

Views: 2052

Answers (2)

Jay
Jay

Reputation: 35659

You can specify access to specific child nodes within the rules. For example

products
  product_0
    likes: 123
    item_price: 1.99
  product_1
    likes: 222
    item_price: 4.99

rules that would only allow reading the likes node by all but limit writing to the admin would look something like this (not tested but something along these lines)

{
  "rules": {
    "products": {
      "$each_product": {
        "likes": {
         ".read": true,
         ".write": "root.child('users').child(auth.uid).child('admin').val() == 'user_is_admin'"
        },
       "item_price": {
         ".read": true,
         ".write": true
       }
      }
    }
  }
}

On the other hand the item_price node could be written to and read by all. None of the other child nodes would be accessible by anyone.

Upvotes: 1

atcastroviejo
atcastroviejo

Reputation: 263

Instead of storing the amount of likes, you could make a list of users who have liked that category/item. Something like this:

likes: {
  userid_1: true,
  userid_2: true
}

That way, you can allow users to edit only their path. Just like you'd normally do with a user list:

".write": "auth.uid === $user"

The true value can be anything really, as users who didn't like the content wont be in the list.

You'll just need to count the number of items in the list to get the number of likes.

And no, you can't have multiple write rules. Instead, use ".validate". Read and write rules cascade, so if one is true, all the others will be ignored. Validate rules don't cascade, they all need to be true

Upvotes: 1

Related Questions