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?
Related
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!
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' "
}
}
}
}
}
I have a locations-orders table that looks like this:
{
"0BW3H9T3R7HJB" : {
"orders" : {
"01750ea0-4980-4bc4-58b2-988c02324e671478636582396" : {
"created_at" : 1478636560000,
},
"01750ea0-4980-4bc4-58b2-988c02324e671478636582483" : {
"created_at" : 1478636560000,
}
}
}
Each location-orders node has an orders node with multiple keys/objects. Those objects have a created_at field on it.
I added this to my database Rules:
{
"rules": {
".read": true,
".write": true,
"users": {
".indexOn": "merchantId"
},
"merchants": {
".indexOn": "locations"
},
"locations-orders": {
".indexOn": ["orders/created_at"]
}
}
}
However, Firebase is still complaining that I'm missing an index:
Using an unspecified index. Consider adding ".indexOn": "created_at" at /locations-orders/1JS53G0TT5ZQD/orders to your security rules for better performance
Am I supposed to run something to create the index? Or is it written incorrectly?
=== UPDATE ===
I changed my file to look into:
{
"rules": {
".read": true,
".write": true,
"users": {
".indexOn": "merchantId"
},
"merchants": {
".indexOn": "locations"
},
"locations-orders": {
"$location_id": {
".indexOn": ["orders/created_at", "orders/status_updated_at"]
}
}
}
}
but I still get the same warning:
Using an unspecified index. Consider adding ".indexOn": "created_at" at /locations-orders/1JS53G0TT5ZQD/orders to your security rules for better performance
If you look at your data structure, there is no orders/created_at under /location-order/$orderId.
{
"rules": {
".read": true,
".write": true,
"users": {
".indexOn": "merchantId"
},
"merchants": {
".indexOn": "locations"
},
"locations-orders": {
"$someid": {
".indexOn": ["orders/created_at"]
}
}
}
}
Try this:
{
"rules": {
".read": true,
".write": true,
"users": {
".indexOn": "merchantId"
},
"merchants": {
".indexOn": "locations"
},
"locations-orders": {
"orders": {
"$orderid": {
".indexOn": "created_at"
}
}
}
}
}
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}$/)"
}
}
}
}
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