I am little bit confused about setting permissions in Rules section of my Firebase database.
I am working on an app (which is a Book actually) and the app must be updated by only one person with this email address: someone#gmail.com. Therefore the rest of people, either authenticated or not, must not be able to modify the contents, but they are allowed to read.
If you look at the Firebase Security Rules API, you'll see that the user's email address (if there is one) is made available via auth.token.email.
So to grant write access to the entire database to the user with the someone#gmail.com email address and read access to everyone else, you could define rules like this:
{
"rules": {
".read": true,
".write": "auth !== null && auth.token.email === 'someone#gmail.com'"
}
}
Said rules would grant read access to everyone. If you wanted to grant read access only to authenticated users, you could use:
{
"rules": {
".read": "auth !== null",
".write": "auth !== null && auth.token.email === 'someone#gmail.com'"
}
}
Related
I'm currently working on a web app that utilises the realtime database. Currently my security rules are set out to allow each user access to their UID path.
"$uid" :{
".read": "auth.uid === $uid",
".write": "auth.uid === $uid"
}
I am now trying to add a admin section, where a specific user has access to the entire database, is there a way to give read/write access to both a specific uid, as-well as the id of the owner of the path?
My database structure looks like the following;
Client -> UID -> Data
I've read about the admin SDKs and user groups, however all I need to do I append items to the database so I think it would be easier if I can just give access to a certain admin user?
Any advice/suggestions would be greatly appreciated!
I typically grant full access to the administrative user at a higher level (sometimes even the root) of the database. For example, say you have a /users node, I'd do:
"users": {
".read": "auth.uid === 'uidOfYourAdminUser'",
".write": "auth.uid === 'uidOfYourAdminUser'",
"$uid" :{
".read": "auth.uid === $uid",
".write": "auth.uid === $uid"
}
}
Since permission cascades down, the admin now has read/write access to all users.
There are many ways to identify the application adminstrator. For example, you could also keep a list of their UIDs in a separate node, like this:
"admins": {
"uidOfYourAdminUser": true
}
And then check it like this in the rules on /users:
root.child('admins').child(auth.uid).exists()
I have implemented Firebase authentication with Gmail, Facebook,Twitter.
I have successfully logged in firebase, Then i have changed Database Authentication rules to below.
{
"rules": {
".read": false,
".write": false
}
}
In firebase console it is showing login users list but while retrieve data it is showing permission denied. Could you please help me to resolve this issue?
if i change above settings to true i can able to read and write data.
Setting both to false will deny read/write access to all users. You can use the auth syntax in your security rules to identify whether or not a user is logged in.
For example, to allow read/write access for logged in users only your rules would look like -
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
As the name (Database Authentication rules) suggests, these rules are for your Firebase-Database, that who should be allowed to read and write the data on your database and who should not be.
So, in your case, what have you done is- You've set both read and write to false. This means no one will be able to either read or write to your database. And that's what is happening (You're not able to write to the database).
But, when you set both of them to true, then everyone will be able to read and write.
So, if you want everyone to be able to read and write to your database, then your rules will look like this:
{ "rules": {
".read": true,
".write": true"
}}
If you want nobody to be able to read and write to your database, like temporary disabling your website or app:
{ "rules": {
".read": false,
".write": false"
}}
If you want everyone to be able to read your database but want only authenticated members to be able to write to your database like they've purchased the premium account and now they can edit the site, then the rules would be:
{ "rules": {
".read": true,
".write": "auth != null"
}}
If you want only authenticated members to be able to read and write to your database, then the rules would be:
{ "rules": {
".read": "auth != null",
".write": "auth != null"
}}
And if you want to explore more about how this stuff works. Then here is the link to official documentation: Understanding Firebase Database Rules
I have a question for my own sanity. Below is one portion of my firebase rules
{
"rules": {
".read": "auth != null",
".write" : false,
"users": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid",
"tokens": {
".write": "(newData.val() < data.val())"
}
}
},
...
If I understand correctly the rules state that:
ALL users must be auth'ed in order to read ANY node
ALL user can NOT write to any nodes
Specific to the User node:
In order to read from your own data, you need to be auth'ed and you can only read your own node
In order to write to your own user data, you must be auth'ed and you can only write to your own node
The user/token node can only be decremented and never increased by any user
Can someone confirm my assumptions/understandings reading Firebase security rules documentation.
Also does anyone have any good articles or helpful tips on using the simulator!?
An important concept with the security rules is that read/write rules "cascade" down the tree. This is discussed briefly in the documentation. That means that as you read your rules from top to bottom, the first rule that grants access takes precedence over any rules specified below it on children of that location.
Addressing each of your items:
ALL users must be auth'ed in order to read ANY node (YES)
ALL user can NOT write to any nodes (non-auth'ed users can NOT write to any nodes)
Specific to the User node:
In order to read from your own data, you need to be auth'ed and you can only read your own node (YES)
In order to write to your own user data, you must be auth'ed and you can only write to your own node (YES)
The user/token node can only be decremented and never increased by any user (see below)
In your current rules, the check for smaller token is not effective because the prior rule granting write access to an auth'ed user overrides it. You also need to address the case where there is no existing token value. My suggestion for fixing that is to use a .validate rule. The documentation recommends:
Used once a .write rule has granted access, to ensure that the data
being written conforms to a specific schema.
{
"rules": {
".read": "auth != null",
".write": false,
"users": {
"$uid": {
".read": "auth.uid == $uid",
".write": "auth.uid == $uid",
"tokens": {
".validate": "!data.exists() || (newData.val() < data.val())"
}
}
}
}
}
As for the Simulator, I don't know of any user guide, but have managed to learn how to use it by experimentation. It's a very effective tool for understand the rules.
Here are a few cases of using the Simulator:
When you open the Simulator, Authenticated is off, which simulates a non-authenticated user. To simulate a read, click on the read button, enter a location: e.g. /users/xyz/tokens, and click on Run. You will see a red X on the lines of the rules that forbid that operation. To simulate an authenticated read, click on the Authenticated button and, for convenience, enter a simple user UID, like "Frank". Now enter location /users/Frank/tokens, click on Run and observe that the read succeeds.
You can do similar tests for writing, entering a location, auth settings and value.
I've been looking on the docs but I couldn't figure out how to prevent duplicated entries if the email exist on a record. There are my current rules
{
"rules": {
"users": {
"$uid": {
// grants write access to the owner of this user account whose uid must exactly match the key ($uid)
".write": "auth !== null && auth.uid === $uid",
// grants read access to any user who is logged in with an email and password
".read": "auth !== null && auth.provider === 'password'"
}
}
}
}
And my record format is:
Thank you very much
Unfortunately you cannot do this type of query in firebase due to it's distributed nature. In general, arrays are extremely tricky and you can read about their limitations in the context of Firebase here.
The way I see it you have two options, you can index your users "array" by the email itself, or you can keep a completely separate object holding all the emails in the system to check against when you make an insert. My suggestion would be the first, set the user object to users/<email>.
In Firebase security rules how can you stop hackers running a script for signup to your website? bare in mind I need them to be able to signup externally on my homepage so I cannot say they need to be logged in.
I know the basic settings from reading Firebase security documentation but I'm worried its not secure enough, especially if someone new my firebase app url to write or read to the database.
In addition it would be good to know the basics I should have so I can check if I do have those.
Currently I have these settings:
{
"rules": {
"users": {
".read": "auth != null",
".write": true,
".indexOn": ["uid", "region"]
}
}
}
Users can write as I need them to sign up but cannot read unless then are logged in. Also have some indexes for performance reasons.
This is where my knowledge stops.
Thanks in advance!
You want to allow users to write, but only to their own user entry. That's actually easy to do with rules:
{
"rules": {
"users": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
". write": "auth != null && auth.uid == $uid"
}
}
}
}
This says /user/{$uid} can only be read or written by a user who is signed in, and who's user ID matches the {$uid} part of the path. Take a look at the rules quickstart for more.