Reputation: 2371
I've been struggling with some firebase security rules. I've been able to add/update data on a node, but I'm not able to remove it. Here are the rules for my node:
"auditions": {
".read": "auth !== null",
"$auditionId": {
"_geoloc": {
".write": "auth !== null && (!data.exists() || !newData.exists() || (data.parent().hasChild('user_id') && data.parent().child('user_id').val() === auth.uid) || (newData.parent().hasChild('user_id') && newData.parent().child('user_id').val() === auth.uid) || (data.parent().hasChild('creator_id') && data.parent().child('creator_id').val() === auth.uid) || (newData.parent().hasChild('creator_id') && newData.parent().child('creator_id').val() === auth.uid))"
},
"band_id": {
".write": "auth !== null && (!data.exists() || !newData.exists() || (data.parent().hasChild('user_id') && data.parent().child('user_id').val() === auth.uid) || (newData.parent().hasChild('user_id') && newData.parent().child('user_id').val() === auth.uid) || (data.parent().hasChild('creator_id') && data.parent().child('creator_id').val() === auth.uid) || (newData.parent().hasChild('creator_id') && newData.parent().child('creator_id').val() === auth.uid))"
},
"creator_id": {
".write": "auth !== null && (!data.exists() || !newData.exists() || (data.parent().hasChild('user_id') && data.parent().child('user_id').val() === auth.uid) || (newData.parent().hasChild('user_id') && newData.parent().child('user_id').val() === auth.uid) || (data.parent().hasChild('creator_id') && data.parent().child('creator_id').val() === auth.uid) || (newData.parent().hasChild('creator_id') && newData.parent().child('creator_id').val() === auth.uid))"
},
"date_created": {
".write": "auth !== null && (!data.exists() || !newData.exists() || (data.parent().hasChild('user_id') && data.parent().child('user_id').val() === auth.uid) || (newData.parent().hasChild('user_id') && newData.parent().child('user_id').val() === auth.uid) || (data.parent().hasChild('creator_id') && data.parent().child('creator_id').val() === auth.uid) || (newData.parent().hasChild('creator_id') && newData.parent().child('creator_id').val() === auth.uid))"
},
"date_last_updated": {
".write": "auth !== null && (!data.exists() || !newData.exists() || (data.parent().hasChild('user_id') && data.parent().child('user_id').val() === auth.uid) || (newData.parent().hasChild('user_id') && newData.parent().child('user_id').val() === auth.uid) || (data.parent().hasChild('creator_id') && data.parent().child('creator_id').val() === auth.uid) || (newData.parent().hasChild('creator_id') && newData.parent().child('creator_id').val() === auth.uid))"
},
"genres": {
".write": "auth !== null && (!data.exists() || !newData.exists() || (data.parent().hasChild('user_id') && data.parent().child('user_id').val() === auth.uid) || (newData.parent().hasChild('user_id') && newData.parent().child('user_id').val() === auth.uid) || (data.parent().hasChild('creator_id') && data.parent().child('creator_id').val() === auth.uid) || (newData.parent().hasChild('creator_id') && newData.parent().child('creator_id').val() === auth.uid))"
},
"instruments": {
".write": "auth !== null && (!data.exists() || !newData.exists() || (data.parent().hasChild('user_id') && data.parent().child('user_id').val() === auth.uid) || (newData.parent().hasChild('user_id') && newData.parent().child('user_id').val() === auth.uid) || (data.parent().hasChild('creator_id') && data.parent().child('creator_id').val() === auth.uid) || (newData.parent().hasChild('creator_id') && newData.parent().child('creator_id').val() === auth.uid))"
},
"is_deleted": {
".write": "auth !== null && (!data.exists() || !newData.exists() || (data.parent().hasChild('user_id') && data.parent().child('user_id').val() === auth.uid) || (newData.parent().hasChild('user_id') && newData.parent().child('user_id').val() === auth.uid) || (data.parent().hasChild('creator_id') && data.parent().child('creator_id').val() === auth.uid) || (newData.parent().hasChild('creator_id') && newData.parent().child('creator_id').val() === auth.uid))"
},
"objectID": {
".write": "auth !== null && (!data.exists() || !newData.exists() || (data.parent().hasChild('user_id') && data.parent().child('user_id').val() === auth.uid) || (newData.parent().hasChild('user_id') && newData.parent().child('user_id').val() === auth.uid) || (data.parent().hasChild('creator_id') && data.parent().child('creator_id').val() === auth.uid) || (newData.parent().hasChild('creator_id') && newData.parent().child('creator_id').val() === auth.uid))"
},
"type": {
".write": "auth !== null && (!data.exists() || !newData.exists() || (data.parent().hasChild('user_id') && data.parent().child('user_id').val() === auth.uid) || (newData.parent().hasChild('user_id') && newData.parent().child('user_id').val() === auth.uid) || (data.parent().hasChild('creator_id') && data.parent().child('creator_id').val() === auth.uid) || (newData.parent().hasChild('creator_id') && newData.parent().child('creator_id').val() === auth.uid))"
},
"videos": {
".write": "auth !== null && (!data.exists() || !newData.exists() || (data.parent().hasChild('user_id') && data.parent().child('user_id').val() === auth.uid) || (newData.parent().hasChild('user_id') && newData.parent().child('user_id').val() === auth.uid) || (data.parent().hasChild('creator_id') && data.parent().child('creator_id').val() === auth.uid) || (newData.parent().hasChild('creator_id') && newData.parent().child('creator_id').val() === auth.uid))"
},
"audition_id": {
".write": "auth !== null && (!data.exists() || !newData.exists() || (data.parent().hasChild('user_id') && data.parent().child('user_id').val() === auth.uid) || (newData.parent().hasChild('user_id') && newData.parent().child('user_id').val() === auth.uid) || (data.parent().hasChild('creator_id') && data.parent().child('creator_id').val() === auth.uid) || (newData.parent().hasChild('creator_id') && newData.parent().child('creator_id').val() === auth.uid))"
},
"is_new": {
".write": "auth !== null && (!data.exists() || !newData.exists() || (data.parent().hasChild('user_id') && data.parent().child('user_id').val() === auth.uid) || (newData.parent().hasChild('user_id') && newData.parent().child('user_id').val() === auth.uid) || (data.parent().hasChild('creator_id') && data.parent().child('creator_id').val() === auth.uid) || (newData.parent().hasChild('creator_id') && newData.parent().child('creator_id').val() === auth.uid))"
},
"message": {
".write": "auth !== null && (!data.exists() || !newData.exists() || (data.parent().hasChild('user_id') && data.parent().child('user_id').val() === auth.uid) || (newData.parent().hasChild('user_id') && newData.parent().child('user_id').val() === auth.uid) || (data.parent().hasChild('creator_id') && data.parent().child('creator_id').val() === auth.uid) || (newData.parent().hasChild('creator_id') && newData.parent().child('creator_id').val() === auth.uid))"
},
"status": {
".write": "auth !== null && (!data.exists() || !newData.exists() || (data.parent().hasChild('user_id') && data.parent().child('user_id').val() === auth.uid) || (newData.parent().hasChild('user_id') && newData.parent().child('user_id').val() === auth.uid) || (data.parent().hasChild('creator_id') && data.parent().child('creator_id').val() === auth.uid) || (newData.parent().hasChild('creator_id') && newData.parent().child('creator_id').val() === auth.uid))"
},
"user_id": {
".write": "auth !== null && (!data.exists() || !newData.exists() || (data.parent().hasChild('user_id') && data.parent().child('user_id').val() === auth.uid) || (newData.parent().hasChild('user_id') && newData.parent().child('user_id').val() === auth.uid) || (data.parent().hasChild('creator_id') && data.parent().child('creator_id').val() === auth.uid) || (newData.parent().hasChild('creator_id') && newData.parent().child('creator_id').val() === auth.uid))"
},
"applications": {
".write": "auth !== null"
}
}
}
I have it setup this way because there are some more complex rules that are needed on all of the sub-nodes of $auditionId
except for applications
.
Is there something I'm doing wrong here with specifying the individual sub-nodes of $auditionId
where when I go to remove data in my app, I get a PERMISSION_DENIED
error?
Upvotes: 0
Views: 90
Reputation: 599111
I want to limit writes/updates/deletes to the creators of the auditions, EXCEPT for when updating
/auditions/$applicationId/applications
That sounds like:
auditions": {
".read": "auth !== null",
"$auditionId": {
".write": "auth !== null && (
(data.exists() && data.child('user_id').val === auth.uid) ||
(!data.exists() && newData.child('user_id').val() === auth.uid)
)",
"applications": {
".write": true
}
}
}
Upvotes: 1