Firebase simulator Read gives permission denied? - firebase

My firebase data looks like this-
My security rules are-
{
"rules": {
"users": {
"fred": {
".read": true,
".write": true
},
"wilma": {
".read": "auth.id == '1'",
".write":true
},
"$other": {
"name": {
".read": true,
".write": true
}
}
}
}
}

First click on Authenticate button.
Path you should enter is /users/wilma

Related

How to properly set rules for multilevel accounts access or permission

In my database, I have this structure.
{
"agencies": {
"a7x6BwW2GDb34sZYiLSDpzApNw03": {
"businessInfo": {},
"clients": {
"V33meLCYD0Q3NATokZNBTxIH1jr2": {
"businessInfo": {}
},
"uRj7uSjVfxNhwG2J5geTlkUUBtC3": {
"businessInfo": {}
}
}
},
"b5riE7yoQEhWabFQn4ZKixTS5513": {
"businessInfo": {},
"clients": {
"A0EwYmU9PLWqnJNIJJ7bvAmvn0F2": {
"businessInfo": {}
},
"XO43avp90NNKo9aQSSilk0pjDvv1": {
"businessInfo": {}
}
}
}
}
}
What I'm trying to do is create a rule that will allow the following:
Each agency should have permissions to read/write each of their clients' Business Info
Clients should have the permissions to read/write their own Business Info
And to add, each Agency and Client will be having their own login and account access.
So far, I was able to do the latter with this rule and the problem with this is the agency can't get through to its clients directory to read and write:
{
"rules": {
"agencies": {
"$uid": {
"businessInfo": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
},
"clients": {
"$uid": {
"businessInfo": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
}
}
}
Here is the code for the request that I've done via the simulation:
{
"auth": {
"uid": "a7x6BwW2GDb34sZYiLSDpzApNw03",
"token": {
"sub": "a7x6BwW2GDb34sZYiLSDpzApNw03",
"firebase": {
"sign_in_provider": "password"
},
"email": "camdevtest00#gmail.com",
"email_verified": true
}
},
"resource": {
"key": "value"
},
"path": "/agencies/a7x6BwW2GDb34sZYiLSDpzApNw03/clients/V33meLCYD0Q3NATokZNBTxIH1jr2/businessInfo",
"method": "get",
"time": "2022-07-12T01:43:21.274Z",
"isAdmin": false
}
I was able to make it work by updating the following rules:
"rules": {
"agencies": {
"$uid": {
"businessInfo": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
},
"clients": {
"$cuid": {
"businessInfo": {
".read": "$uid === auth.uid || $cuid === auth.uid",
".write": "$uid === auth.uid || $cuid === auth.uid"
}
}
}
}
}
}
}
Basically I used two different uids ($uid for the Agency, $cuid for the Client) so the rule can determine which is currently the authenticated user, and give them read/write access respectively.
Thanks for the help!

How to set Firebase Realtime Database Security Rules for specific email domain and allow read write to multiple parent nodes

How to set security rules for Firebase realtime database structure as below:
users: {
...
...
...
},
books: {
...
...
...
},
sales: {
...
...
...
}
Condition: Firebase auth is set to email/password and only user logged-in with emails ending with domain [mydomain.co.in] must be able to read or write to parent node. Without using custom claims.
Adding below security rules is applied/working only for the the first parent node [users] and not to all, what is a miss here?
{
"rules": {
".read": false,
".write": false,
"users": {
".read": "auth.token.email.matches(/.*#mydomain.co.in$/)",
".write": "auth.token.email.matches(/.*#mydomain.co.in$/)",
".indexOn": "name"
},
"books": {
".read": "auth.token.email.matches(/.*#mydomain.co.in$/)",
".write": "auth.token.email.matches(/.*#mydomain.co.in$/)",
".indexOn": "title"
},
"sales": {
".read": "auth.token.email.matches(/.*#mydomain.co.in$/)",
".write": "auth.token.email.matches(/.*#mydomain.co.in$/)",
".indexOn": "price"
},
}
}
Try below enclosed within uid field?
Reference https://firebase.google.com/docs/reference/security/database
same code works with auth.token.email.matches(/.*#mydomain.co.in$/)
{
"rules":{
".read": "false",
".write": "false",
"users":{
"$uid":{
".read":" auth.token.email.endsWith('#mydomain.co.in')",
".write":" auth.token.email.endsWith('#mydomain.co.in')",
".indexOn":"name"
}
},
"books":{
"$uid":{
".read":" auth.token.email.endsWith('#mydomain.co.in')",
".write":" auth.token.email.endsWith('#mydomain.co.in')",
".indexOn":"title"
}
},
"sales":{
"$uid":{
".read":" auth.token.email.endsWith('#mydomain.co.in')",
".write":" auth.token.email.endsWith('#mydomain.co.in')",
".indexOn":"price"
}
}
}
}
Auth Token payload
{
"token":{
"email": "test#mydomain.co.in"
}
}

Firebase Security rules, disable write on specific node

My firebase structure looking like that:
{
"post": {
"uid": {
"text": "Name";
}
},
"games": {
"id": {
"title": "buttons",
"text": "(user id string)"
},
"id": {
"title": "navbars",
"text": "(id string)"
}
},
"guides": {
"1": {
"title": "guide",
"text": "unwriteable string"
}
}
}
(The value doesn't matter..)
I want to allow read and write on everynode, execpt the guides node,
so I tried the following rules:
{
"rules": {
".read": "auth == null",
".write": "auth == null",
"guides": {
".write": false
}
}
}
But. unfortunately, because of the 'father' allowance, firebase doesn't care about the guides specific rule,
Any idea how to achive my goal?
Bacause firebase security rules cascade you can't say someone has permission to write everywhere and later say but not here.
So in you case you would have to add rules for your other paths like this:
{
"rules": {
".read": "auth == null",
"guides": {
".write": false
},
"games": {
".write": "auth == null"
},
"post": {
".write": "auth == null"
}
}
}
As Kato stated this can also be done with the following rule:
{
"rules": {
".read": "auth == null",
".write": "auth == null && !newData.hasChild('guides')"
}
}
The first example will allow you to write only in the games and post nodes whereas the second example will allow you to write everywhere except for the guides node.

Firebase 3 auth via slug?

I'm trying to implement my database rules on my firebase database.
for now I have:
{
"rules": {
".read": false,
".write": false,
"users": {
".read": true,
".write": "(auth != null) && !root.child('users/'+ newData.child('slug').val()).exists()",
"$username": {
".read": false,
".write": false,
"clubs": {
".read": "(auth != null)",
".write": false
},
"roles": {
".read": "(auth != null)",
".write": false
}
}
},
"clubs": {
".read": true,
".write": true
}
}
}
and the data looks like following:
{
clubs: {
smash_for_fun: {
description: "The best club ever!",
name: "Smash For Fun",
slug: "smash_for_fun",
users: {
glenn_lastname: true
}
}
},
users: {
glenn_lastname: {
clubs: {
smash_for_fun: true
},
name: "Glenn Lastname",
slug: "glenn_lastname",
uid: "edtJDkUnEOXAUnl0J9GfXIsOqgG2"
},
other_user: {
name: "Other user",
slug: "other_user",
uid: "sgsdkjfnsdfnsdkjfnlsdfndsjfn"
}
}
}
but how can i make the rules so a user can only write his own details, but not from a other user?
and how to check if the user.slug doesn't exists?

Validate a Firebase Key is an integer

Here is the database schema:
Here are the rules:
"notifications": {
"$year": {
".read": "false",
".write": "!data.exists()",
"$month": {
".read": "false",
".write": "!data.exists()",
"$day": {
".read": "false",
".write": "!data.exists()",
"$hour": {
".read": "false",
".write": "!data.exists()",
"$minute": {
".read": "false",
".write": "!data.exists()",
"$data": {
".read": "false",
".write": "!data.exists()"
}
}
}
}
}
}
How can I validate (using ".validate" or ".write" rules) that the users can enter only integers into that tree? Or is there some workaround?
What I am trying to achieve is to create write only (no deletes, or updates) log that has some structure and will be processed later. I can change the structure for example to something like 2015-10-6-17-30 for the key, or something else. I just can't believe that Firebase does not have something for this situation.
Update:
This is not duplicate, I am searching for a workaround, or something else that will help me achieve what I am after.
To validate that a key is a number:
{
"$key": {
".validate": "$key.matches(/^[0-9]+$/)"
}
}
But please read about array-like behaviors in Firebase. Hint: probably use a prefix like "y2015", "m12", etc. to avoid some unexpected results with using numbers.
If using push IDs works for you, here's a security rule structure you could use.
{
"notifications": {
"$notification_id": {
".write": "!data.exists()",
".read": "false",
".validate": "newData.hasChildren(['time', 'state', 'message'])",
"time": {
".validate": "newData.val().matches(/YOUR REGEX/)"
},
"state": {
".validate": ""
},
"message": {
".validate": ""
}
}
}
}
Obviously you'll need to fill in the blanks. The main thing here is that you can use a regex to match the time field.
The actual data would look like:
{
"notifications": {
"-K-z5koYf8mYZu5OfSGR": {
"time": "2015-10-06-17-30",
"state": 1,
"message": "foo"
},
"-K-z5koYf8mYZwgwsfGx": {
"time": "2015-10-06-17-30",
"state": 1,
"message": "bar"
}
}
}

Resources