2

I have endpoints:

/schools/$schoolId/rooms/$roomName/id
/schools/$schoolId/rooms/$roomName/name {must be unique ignoring case} 
/schools/$schoolId/rooms/$roomName/{other attributes not relevant i think}

I want no two rooms to have the same name so I'm storing it as the key. I'm converting the names to lowercase before setting the value and so I have these security rules:

{
  "rules": {
    ".read": "auth != null",
    ".write": "auth != null",
    "schools":{
      "$schoolId":{
        "rooms":{
          "$roomName":{
            ".validate": "$roomName===newData.child('name').val().toLowerCase() && !data.parent().child(newData.child('name').val().toLowerCase()).exists()"
          }
        }
      }
    }
  }
}

These rules do not allow me to write any new rooms.

Community
  • 1
  • 1
Vinay Nagaraj
  • 1,162
  • 14
  • 26
  • You'll need to create a helper data structure to ensure that uniqueness. See http://stackoverflow.com/questions/25294478/how-do-you-prevent-duplicate-user-properties-in-firebase – Frank van Puffelen May 30 '16 at 14:44
  • @FrankvanPuffelen I'd like to avoid the data duplication if possible. I was wondering why this rule I'm trying doesn't work. – Vinay Nagaraj May 30 '16 at 15:48
  • Program managed data duplication is completely normal in NoSQL. In this case what you need to build is extremely similar to a "unique index" in most relational databases. The only difference is that it's your code that builds/maintains the index, instead of the DBMS. See this article on [NoSQL Data Modeling](https://highlyscalable.wordpress.com/2012/03/01/nosql-data-modeling-techniques/). – Frank van Puffelen May 30 '16 at 16:27
  • @FrankvanPuffelen I realised my rule was sitting on the wrong level. I've edited in the new rule i'm using and it *seems* to be working. This doesn't rely on any data duplication, would it cause any problems I'm not seeing? – Vinay Nagaraj May 31 '16 at 07:00
  • Can you please share the edited rule @VinayNagaraj – Urja Pawar Jul 31 '16 at 11:15
  • @UrjaPawar the rule in my question is the edited one. – Vinay Nagaraj Aug 01 '16 at 15:31

1 Answers1

1

You can provide a role for the property name inside the single room.
Something like this:

"rooms":{

 //A Room 
 "$roomId": {
    "name": {
        ".write": "!data.exists()"
    }
  }  
}
Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841