i have this schema
"Photo": {
"$User": {
"$Photo": {
".validate": "auth.uid == $User && ((newData.hasChildren(['created', 'updated', 'image', 'title']) && data.val() == null && newData.val() != null) || data.val() != null && newData.val() != null && newData.child('updated').val() != null)",
"created": {
".validate": "newData.isNumber() && data.val() == null && newData.val() != null && newData.val() == now"
},
"updated": {
".validate": "newData.isNumber() && newData.val() == now"
},
"image": {
".validate": "newData.isString() && data.val() == null && newData.val() != null"
},
"title": {
".validate": "newData.isString() && newData.val().length > 3"
},
"$other": {
".validate": "false"
}
}
}
}
if you see my validate rule
".validate": "auth.uid == $User && ((newData.hasChildren(['created', 'updated', 'image', 'title']) && data.val() == null && newData.val() != null) || data.val() != null && newData.val() != null && newData.child('updated').val() != null)"
i write a permission only for write and for the update but when i delete a node i can delete it. my goal is to prevent the delete. why this? where the error? thanks in advance
For this you'll want to use a .write rule, not a .validate rule. From the docs:
Additionally, the validate definitions are ignored when data is deleted (that is, when the new value being written is null).
Related
Firebase database question:
I want to "open" "votes" for unauthenticated users. Is this safe ?
Maybe:
{
"rules": {
".read": true,
"posts": {
"title": { ".write": "auth != null && auth.uid == 'XXXXXX'"},
"url": { ".write": "auth != null && auth.uid == 'XXXXXX'"},
"time": { ".write": "auth != null && auth.uid == 'XXXXXX'"},
"vote": {".write": true,}
}
}
}
Or:
{
"rules": {`enter code here`
".read": true,
"posts": {
"title": { ".write": "auth != null && auth.uid == 'XXXXXX'"},
"url": { ".write": "auth != null && auth.uid == 'XXXXXX'"},
"time": { ".write": "auth != null && auth.uid == 'XXXXXX'"},
"vote": {".write": "newData.val() === data.val() + 1"}
}
}
}
I have a structure like this :
posts: {
group:{
postId: {
nbLikes: ..,
nbComments: ...,
updatedAt: ...,
text: ...
}
}
}
and I would like to allow the author to remove it, and everyone else to update everything except the text.
I have tried with this:
"posts": {
"$group": {
"$post": {
".write": "(data.exists() && !newData.exists() && data.child('userId').val() === auth.uid)
|| (data.exists() && newData.exists() && auth.uid != null)
|| (!data.exists() && newData.child('userId').val() === auth.uid)",
"text": {
".write": false
}
},
}
},
but unfortunately it does not work.
Moreover, when I try doing,
"posts": {
"$group": {
"$post": {
"text": {
".write": false
},
"nbLikes": {
".write": true
},
"nbComments": {
".write": true
}
....
},
}
},
it doesn't work either
Thanks for your help !
{
"rules": {
"interviews": {
".read": true,
".write": "auth != null && root.child('admins').child(auth.uid).exists()",
"thumbnail" :{
".validate" : "newData.val() != 0 || (newData.val() == 0 && data.val() == 'uploading')"
},
"soundbyte" :{
".validate" : "newData.val() != 0 || (newData.val() == 0 && data.val() == 'uploading')"
}
},
"token": {
".read": false,
".write": "auth != null && auth.isAdmin == true"
},
"admins":{
".read" : false,
".write": "auth != null && auth.isAdmin == true"
}
}
}
Can you tell any problem with my security rules, as I am trying to add a validation to my thumbnail's data.
Here is a little data structure example I am gonna use with it.
interviews
-K_l_pkOTUYovqRwajln
detail: "YO"
soundbyte: "interview_sb_KlpkOTUYovqRwajln.mp3"
thumbnail: "uploading"
title: "Episode Five"
video_url: ""
-K_ll31srQ46vgtDXX1n
detail: "Duncan lives in a town."
soundbyte: "interview_sb_KllsrQvgtDXXn.mp3"
thumbnail: "interview_thumb_KllsrQvgtDXXn.jpg"
title: "Duncan"
video_url: ""
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)"
}
}
}
}
}
I want to allow all logged in user access to create new content, but only those who are owners should be able to update the data. I can't figure out how to do this, this is what I have tried:
{
"rules": {
".read": false,
".write": false,
"videos": {
".read": true,
".indexOn": ["id", "title_lower_case"],
"$video": {
".write": "(auth !== null && auth.provider === 'password' && (!newData.exists() || newData.hasChildren())) || (auth.uid === root.child('videos').child($video).child('uid').val())",
".validate": "newData.hasChildren(['id', 'title', 'title_lower_case', 'uid'])",
"id": {
".validate": "newData.isString() && newData.val().length >= 5 && newData.val().length <= 1000"
},
"title": {
".validate": "newData.isString() && newData.val().length >= 2 && newData.val().length <= 1000"
},
"title_lower_case": {
".validate": "newData.isString() && newData.val().length >= 2 && newData.val().length <= 1000"
},
"uid": {
".validate": "newData.val() === auth.uid"
},
"$other": {
".validate": false
}
}
},
"users": {
".read": true,
"$user": {
".read": "auth !== null && auth.provider === 'password'",
".write": "auth.uid === $user && (!newData.exists() || newData.hasChildren())",
".indexOn": "name_lower_case",
".validate": "newData.hasChildren(['email', 'name', 'name_lower_case'])",
"email": {
".validate": "newData.isString() && newData.val().length <= 2000"
},
"name": {
".validate": "newData.isString() && newData.val().length >= 2 && newData.val().length <= 2000"
},
"name_lower_case": {
".validate": "newData.isString() && newData.val().length >= 2 && newData.val().length <= 2000"
},
"$other": {
".validate": false
}
}
}
}
}
I thought that this part allowed any logged in user to create a new node:
auth !== null && auth.provider === 'password' && (!newData.exists() || newData.hasChildren())
And this part only allowed owners to edit the node:
auth.uid === root.child('videos').child($video).child('uid').val()
Btw, I use the simple login feature in firebase if that has anything to say.
Doing the below seemed to do the trick. If the auth variable exists, then allow write abilities. Due to me not fully understanding these rules, I have to wonder if this is running against the current user or if it's checking to see if any user is logged in.
{
"rules": {
"product":{
".read": true,
".write":"auth !== null"
}
}
}