5

So far I've been using this rules configuration

{
  "rules": {
    "items": {
      ".read" : true,
      "$uid": {
        ".read" : true,
        ".write": "auth != null && auth.uid == $uid"
      }
    }
  }
}

validation and other directories omitted. /items/user1/item1 /items/user2/item1

All can read items directory and all user items (no private items)

What do I need?

flat array of items

"items" : {
     "item1": {},
     "item2": {}
}

with userId as property

"item1" : {
    "uid": "userId"
}

Only user created item can edit/delete it, but all can see it.

I was thinking about double items in different directory such as

"public_items": {
         "item1": {},
         "item2": {}
}


"items": {
   "userId": {
      "item1": {},
      "item2": {},
   }
}

But it seems like not a good idea.

Rules are applied in an atomic manner. That means that a read or write operation is failed immediately if there isn't a rule at that location or at a parent location that grants access. Even if every affected child path is accessible, reading at the parent location will fail completely. https://firebase.google.com/docs/database/security/securing-data#read_and_write_rules_cascade

if rules can't be applied for each item, how to build items directory with different owners ?

Community
  • 1
  • 1
toasty
  • 142
  • 1
  • 1
  • 10

1 Answers1

8

You can handle this only using the /items/itemId/uid.

{
  "rules": {
    "items": {
        ".read" : true,
        "$itemId": {
            ".write": "(!data.exists() && newData.child('uid').val() == auth.uid ) || (data.child('uid').val() == auth.uid && newData.child('uid').val() == auth.uid)"
        }
    }
  }
}

Above rules is a possible solution. We are allowing anyone to read everything that is inside items. But only users who owns the item (/itemId/uid) can create/edit. Also we are forcing that the new or edited item has the user id.

adolfosrs
  • 9,286
  • 5
  • 39
  • 67