3
votes

I am really struggling with firebase database security rules.

I am working on a simple app, where users can maintain a list of records, which anyone can read but only the user who created the record can edit or delete.

Just consider it like a todo app, where authenticated users can manage list of tasks. Users can read each others task list but only the user who created the task can delete or edit it.

I have tried different options but failed to come up with correct security policy.

Is there any example I can follow or any recommendation on how to structure the data to simplify security policy ?

Sample security rule

I have tried something like this -

"rules": {
"records" : {
  ".read" : true,
    "$user_id": {
         ".write": "auth.uid === $user_id"
        }
    }
  }
}

So that anyone can read records but only logged in user with matching user_id should be able to add, edit or delete a record.

However, when I try a write action in simulator, I always get write denied error. I am passing the auth uid as "user_id" in request body/data.

I have also tried

{
 "rules": {
 "records" : {
   ".read" : true,
    ".write": "auth.uid === data.child('user_id').val()"
     }
   }
}
2
You should post what have you tried and what is wrong with it. - api55
@api55 I have updated the question with sample security rule. - am17

2 Answers

5
votes

I found this in the documentation. The node users has childs stored with auth.uid as a key. So you basicly compare the users uid to the key before writing to that entry:

{
  "rules": {
    "users": {
      "$user_id": {
        // grants write access to the owner of this user account
        // whose uid must exactly match the key ($user_id)
        ".write": "$user_id === auth.uid",
        ".read": true
      }
    }
  }
}

https://www.firebase.com/docs/security/guide/user-security.html

0
votes

Try to add the following node -> "$record_id": {}

{
 "rules": {
 "records" : {
   "$record_id": {
      ".read" : true,
       ".write": "auth.uid === data.child('user_id').val()"
        }
      }
   }
}