How to validate location path in Firebase Rules? - firebase

I would like to validate $username length to be longer than 5 character and shorter than 24 character
{
"rules": {
"user": {
"$username": {
".write": "auth != null",
"uid": {},
"created": {},
"lastlogin": {}
}
}
}
}
(if it's possible) How can i do that?

Yes it is possible:
{
"rules": {
"user": {
"$username": {
".write": "auth != null",
".validate":"newData.hasChildren(['validate_username'])",
"validate_username":{
".validate":"
newData.val() == $username
&& newData.val().length > 5
&& newData.val().length < 24
"
},
"uid": {},
"created": {},
"lastlogin": {}
}
}
}
}

you can validate the $username with a regex
{
"rules": {
"user": {
"$username": {
".write": "auth != null",
".validate": "$username.matches(/^.{6,23}$/)"
}
}
}
}

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!

Firebase realtime database rules simulation failed

This is my firebase json data.
{
"Users": {
"MyData": {
"002ab7bUmab1CgQsw53abB3g1Ab1": { //UID
"-A3ABlabkflA_ABabABA": { //this is the databaseReference.child(DBHelper.FIREBASE_POSTS).push().getKey();
"display": "123",
"result": {
"format": "1",
"id": 1,
"numBits": 0,
"syncFirebaseId": "-A3ABlqmkflA_AVabABA",
"syncStatus": -1,
"text": "1234567",
"timestamp": 1514496903005
}
},
"-A2ABlabkf2A_ABabABA": { //this is the databaseReference.child(DBHelper.FIREBASE_POSTS).push().getKey();
"display": "123",
"result": {
"format": "1",
"id": 1,
"numBits": 0,
"syncFirebaseId": "-A3ABlqmkflA_AVabABA",
"syncStatus": -1,
"text": "1234567",
"timestamp": 1514496903005
}
}
}
}
}
}
Rules:
{
"rules": {
"Users": {
"MyData": {
"$uid": {
".read": "auth != null && auth.uid == $uid"
}
}
}
}
}
But when I simulate, read operation is denied. I want to allow only authenticated user to update data node that is relevant to his/her own. That user should not be able to edit other's data node (UID).
Here is the result of read simulation:
You're trying to read the root of your database. Since your rules grant nobody access to the entire database, the read is rejected. If you simulate reading from /Users/MyData/$theUidThatYouStruckOut it will be allowed.
I think auth.uid == $uid" should be auth.uid === $uid". For more information go through this
You have change Rules
{
"rules": {
"Users": { *** This Line
"MyData": {
"$uid": {
".read": "auth != null && auth.uid == $uid"
}
}
}
}
}

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.

I can't get the user uid signed in in the rules of the firebase console

Here is my data.
"users" : {
"user1": {
"1234": {
"role": "admin"
},
"1235": {
"role": "normal"
}
},
"user2": {
"1236": {
"role": "admin"
},
"1237": {
"role": "normal"
}
}
}
And here is rules for that.
"rules" {
"users": {
".read": "root.child('users').child('user1').child(auth.uid).child('role') === 'admin'"
}
}
But the rule doesn't work. I seem the auth.uid isn't gotten correctly.
Try this :-
{
"rules": {
"users": {
"user1": {
"$user_id": {
".read": "$user_id === auth.uid && root.child('users/user1/' + $user_id + '/role/').val() === 'admin' "
}
}
}
}
}

Unable to validate child nodes with Firebase security

I'm clearly missing some fundamental aspect of firebase security, because this shouldn't work. I would expect it to throw a validation error when attempting to push invalid data. (Inserting a new node into /nodes)
Rules:
{
"rules": {
"nodes": {
".read": "auth !== null && auth.provider === 'google'",
".write": "auth !== null && auth.provider === 'google'",
"user": {
".validate": "newData.val() === auth.uid"
},
"ts": {
".validate": "newData.val() <= now && newData.val() >= (now-1000*60*60*24)"
}
}
}
}
Then in my console I try to intentionally insert invalid data:
ref.child('nodes').push({
'user': 'abc',
'ts': 123
}, function(err){console.log(err);});
Which logs null, and when I check my database it was inserted, no validation errors! I know I've got something fundamentally wrong, because a validation rule right after the .read and .write rows of the following disallows any writing. .validate": "newData.hasChildren(['user', 'ts'])",
{
"nodes" : {
"-KAgH0BLneWfGu8NymBo" : {
"ts" : 123,
"user" : "abc"
}
}
}
Whoops. Missing "$node_id"
{
"rules": {
"nodes": {
"$node_id":{
".read": "auth !== null && auth.provider === 'google'",
".write": "auth !== null && auth.provider === 'google'",
"user": {
".validate": "newData.val() === auth.uid"
},
"ts": {
".validate": "newData.val() <= now && newData.val() >= (now-1000*60*60*24)"
}
}
}
}
}

Resources