Dynamic security rules for "endless" children in Firebase? - firebase

Hey so I have this Firebase layout where I have files and every file can have children and all the children can have children, etc. How would I set up my security rules to dynamically work for the children (32 max if I'm remembering it correctly?). It kind of has to work with different read/write permissions depending on the user etc.
This is how it would work in a perfect world:
{
"rules": {
"users": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid",
"files": {
"$file": {
// permissions ...
"children": {
"$file": {
// permissions ...
"children": {
// etc ...
}
}
}
}
}
}
}
}
}

Related

Firebase rules: Unknown variable '$uid'

I want user to only access their own content, except for one child node: common
In common child node I want all signed in users to have access.
I have made the following rules:
{
"rules": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
},
"common" : {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
}
}
Firebase gives me the error:
Error saving rules - Line 8: Unknown variable '$uid'.
The error appears in this line: ".read": "auth != null && auth.uid == $uid",
Based on your question, this is your desired database structure:
{
"userIdA": { // anything here can be written by only userIdA
"name": "Tom", // this is just example data
"location": "London",
/* ... */
},
"userIdB": { // anything here can be written by only userIdB
"name": "Sarah",
"location": "New York",
/* ... */
},
/* ... other user data ... */
"common": { // anything here can be written by signed in users
"data1": "some value",
"data2": "some other value",
}
}
The rules for this structure would be:
{
"rules": {
"common" : {
".read": "auth != null", // logged in users can read
".write": "auth != null" // logged in users can write
},
"$uid": { // $uid will be the value of any key, that isn't listed above it (in this case, anything other than "common")
".read": "$uid === auth.uid", // only the matching user can read
".write": "$uid === auth.uid" // only the matching user can write
}
}
}
Note: This data structure isn't very secure. Allow read/write access to only what you need in your database. With this structure, any user could come along and open up their console and delete everything under "/common". You may consider adding ".validate" rules to make sure certain keys (such as "/common/data1") are only strings.
The $uid must be inside users Document like the example below :
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}

Firebase how to apply update roles on custom child

how to allow non authenticated user to update only highlighted child and only read other child
current roles is
{
"rules": {
".read": true,
".write":"auth != null"
}
}
I have got the answer
{
"rules": {
".read": true,
".write":"auth != null",
"$product": {
"$id": {
"showen":
{
".write": true
}
}
}
}
}

Firebase Database Rules

I'm having some issues wrapping my head around the database rules and the documentation isn't helping. I am trying to set things up so that only the user can delete their own items, however at the moment I'm getting permission_denied errors. I am assuming that it is because I don't have a read/write rule on the 'items' level. However I feel that if I just added a 'auth != null' rule it would give to much permission. Any thoughts?
the database setup:
users:
{
user_1 {
items:
{
item_1: true,
item_2: true,
}
},
user_2 {...},
etc {...},
},
items:
{
item_1
{
user: "user_1"
....
},
item_2
{
user: "user_1"
....
},
}
The database rules look like
{
"rules": {
"users": {
"$uid":{
".read": "auth != null && auth.uid==$uid",
".write": "auth != null && auth.uid==$uid"
}
},
"items": {
"$itemID": {
".read": "root.child('Users/'+auth.uid+'/'+$itemID).exists()",
".write": "root.child('Users/'+auth.uid+'/'+$itemID).exists()"
}
}
}
}
At the moment any user can delete any item.
To ensure that only the owner can delete the item, you need to not just verify that:
"items": {
"$itemID": {
".read": "auth.uid == data.child('user').val()",
".write": "auth.uid == data.child('user').val()"
}
}
There is no need to check if they exist in the /users node as far as I can tell, although you can easily add that back if needed.
But if a user can only read/write their own items, I'd model the data differently:
"items": {
"$uid": {
".read": "auth.uid == $uid",
".write": "auth.uid == $uid"
"$itemID": {
}
}
}
This is much simpler to model and will give you much better scalability, since the database only ever has to consider the data for one user.

Firebase Security Rules allowing conditional .read

I want to create a firebase rule that allows users to read and write to child if a property of that child has a specific value. Let's say my database looks something like this:
"tasks": {
"SDkh7s62jnd23d9": {
"uid": "someuserid",
"other": "datagoes here"
}
}
Here is my current security rule:
"tasks": {
".indexOn": "_state",
"$registerQueueKey": {
".read": "data.child('uid').val() == auth.uid",
".write": "newData.child('uid').val() == auth.uid"
}
}
This rule restricts user write permissions, but it never lets a user read, even if the child they are attempting to read has a uid property that equals auth.id.
I then tested the following rule set:
"tasks": {
".indexOn": "_state",
"$registerQueueKey": {
".read": true,
".write": "newData.child('uid').val() == auth.uid"
}
}
Despite the .read permission being set to a permanent true value, the user still cannot read the $registerQueueKey child.
I then tested the following rule set:
"tasks": {
".indexOn": "_state",
".read": true,
"$registerQueueKey": {
".write": "newData.child('uid').val() == auth.uid"
}
}
Now I can read the child fine, so I attempted this final security rule:
"tasks": {
".indexOn": "_state",
".read": "data.child($registerQueueKey").child('uid').val() == auth.uid",
"$registerQueueKey": {
".write": "newData.child('uid').val() == auth.uid"
}
}
But this rule throws an error because the variable $registerQueueKey is undefined in the scope it is being used.
How do I accomplish a rule like this?
I think the error is because you have not placed a wildcard:
"tasks": {
"$uid": {
".indexOn": "_state",
".read": "data.child($registerQueueKey").child('$uid').val() == auth.uid",
"$registerQueueKey": {
".write": "newData.child('$uid').val() == auth.uid"
}
}
}

Allow user to read only own content with firebase rules?

I'm trying to set users to get only own objects. I have a tasks which have 3 attributes on fb-database: task-text, datetime, user. user have user uid. I want to write a rule that allow user to read only own tasks.
So far I have this and it dont work:
{
"rules": {
"tasks": {
".read": "auth.uid == data.child('user').val()",
".write": "auth.uid != null",
}
}
}
You'll want to break up the tasks by user, so you'll have a structure that looks like:
root
tasks
Puf
...
Andrew
...
James
...
This can be secured via rules that look like:
{
"rules": {
"tasks": {
"$userId": {
".read": "auth.uid == $userId",
".write": "auth.uid == $userId",
}
}
}
}

Resources