I'm trying to restrict the "Stores" write to the owner only, but the "write" rules does not seem to work
"Stores": { // restrict "Stores" write to the owner only
".read": "true",
".write": "auth.uid !== null && auth.uid === newData.child('ownerID').val()"
}
... and surprisingly neither does this..
".write": "newData.child('ownerID').exists()"
However it works with this...
".write": "auth.uid !== null"
But it is not as secure as how I want it. Can anyone help please?
You've defined the rule on the wrong level. Right now you're controlling who can write to the /Stores node. But what you want to do, is control who can write an an individual store, so /Stores/$storeid.
Something like:
"Stores": {
"$storeid": {
".write": "auth.uid !== null && auth.uid === newData.child('ownerID').val()"
}
}
Related
I have a mobile application which reads the data from the firebase server without firebase login/authentication (posts and news) and I want to create an admin webpage where I can log in and add, or modify news, so I need a write permission there. My rules are currently:
{
"rules": {
".read": true,
".write": "auth !== null && ?????
}
}
Can I write something like "user.emailAddress == 'mail#example.com'"?
You can create a users table on database like
{
"users":{
"your UID":{
"isAdmin": true
}
}
}
Then edit rules :
{
"rules": {
".read": true,
".write": "auth.uid != null && root.child("users").child(auth.uid).isAdmin === true"
}
}
You might want to start by reading the documentation about securing user data. There is a lot to know here.
One possibility is using the known user's uid to restrict access. The auth.uid variable contains the uid.
".write": "auth.uid == 'the-known-uid'"
Also you can use auth.token to access some other things about the user, including email address (which may not be present):
".write": "auth.token.email == 'the#email.address'"
You can also use custom authentication tokens, which also is covered in the documentation.
Create database:
{
"users":{
"your UID":{
"isAdmin": true
}
}
}
Set rules:
Wrong:
{
"rules": {
".read": true,
".write": "auth.uid != null && root.child("users").child(auth.uid).isAdmin === true"
}
}
Right:
{
"rules": {
".read": true,
".write": "auth.uid != null && root.child('users').child(auth.uid).child('isAdmin').val() === true"
}
}
I have a database like this:
The first key is the userId, has to be connected, and the next keys only him can read and write. How I can manage the rules to be safe and no one can't see the key of each other ? I begin with that but I don't think is enough
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
Because you are using the user ID as a key you can use it in your rules to make sure users can only read/write to their own nodes like this:
{
"rules": {
"$user_id": {
".write": "$user_id === auth.uid",
".read": "$user_id === auth.uid"
}
}
}
For more information you can take a look at the firebase docs about User Based Security and Securing Data. For a more extencive answer about linking users to their data you can take a look at my answer here.
So I'm delving into Firebase security rules and as far as I understand, rules that are specified higher up in the tree cascade further down into the tree.
So I'm wondering if there's a way to make a case work where I basically have a /bands subtree that I want writeable by anyone, however there are admins and members subtrees where I want only writeable, based on special conditions.
So far, this is kinda what I have going on:
{
"rules": {
".read": "auth != null",
"bands": {
"$bandId": {
".write": "auth !== null",
"$bandId": {
".write": "auth !== null && data.child('creator_id').val() === auth.uid"
}
}
}
}
}
When I go to test "writing", in the Firebase simulator, something like /bands/-KnLeIHM4zCspwBZjZP9 where the creator_id does NOT match the specified auth.uid I have provided, I still get a simulator write success, due to the /bands tree-level having the write access.
Is there any clever way to do allow anyone to "push" to /bands but then when it gets down to the actual /bands/$bandId level, it starts looking at these various conditions? Or am I going to have to rework my data and separate out the trees into even more trees? I have other instances where this kind of thing is necessary, but this is the most succinct version I am working with that I need to solve.
Any thoughts? Thanks in advance :)
{
"rules": {
"bands": {
".read": "auth != null",
".write": "!data.exists() && auth != null",
"$bandId": {
".write": "data.child('creator_id').val() === auth.uid"
}
}
}
}
".write": "!data.exists() && auth != null" will only allow authenticated users to write to paths within bands if they don't exist (creating new content).
I've got a data structure like this:
How can I access /Restaurant/-KK37k6g5cYYippEHpZ3/User/-KK37k6g5cYYippEHpZ4/id's value within the firebase security rules? The two push keys should be wildcards. I need something like this:
"Restaurant": {
"$id": {
".read": "auth.uid != null",
".write": "data.child($id).child('User').child($anotherWildcard).child('id').val() === auth.uid"
}
}
Not sure if I fully understood what you are asking for but here goes my thoughts.
The first problem in your rule is that you are specifying child($id) but you already are inside the $id. it is implicit in your data that you are referring to $id.
To resolve your main problem you wont need another wildcard. You can just use hasChild to verify if the auth.uid is inside restaurant/user.
"Restaurant": {
"$id": {
".read": "auth.uid != null",
".write": "auth.uid != null && data.child('User').hasChild(auth.uid)"
}
}
I've database structure like
appointments
[$userId]
[$appointmentId]
message:"something"
date:"14/12/2015"
users
[$userId]
name: Hardik
email: hardikmsondagar#gmail.com
And I'm using angularfire library of Firebase, I'm trying to restrict read operation based on uid ( means a person who created appointment only can read that). I've tried following security rule
{
"rules": {
"appointments": {
"$userId":{
"$appointmentId":{
".read": "auth.uid==$userId",
".write": true
}
}
},
"users": {
"$userId":
{
".read": "auth!=null && $userId === auth.uid",
".write": "auth!=null && $userId === auth.uid"
}
}
}
But end up on this error
Error: permission_denied: Client doesn't have permission to access the desired data.
I'm trying to access all the user's appointments using following code
var ref = new Firebase("https://<FIREBASE-APP>.firebaseio.com/appointments/"+uid);
$scope.appointments = $firebaseArray(ref);
Set rules for the $uid wildcard, to read all the children.
"appointments": {
"$uid":{
".read": "auth.uid == $uid",
".write": "auth.uid == $uid",
}
}
The $uid wildcard sets permissions for the entire list, whereas the $appointmentId wildcard sets permissions for each individual item.
But Security Rules cascade, so you only need to set the rules for the top level.
Read the docs on cascading for more information.