How to access parent auth status in array - firebase

I'm not sure whether the title of this is appropriate as I'm new to Firebase Authentication and rules, however, I have successfully setup authentication and am now trying to protect a particular route and can't seem to access the relevant data, here's my Firebase rules on my realtime database:
{
"rules": {
"accounts": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
},
"demo": {
".read": "accounts.$uid === auth.uid",
".write": true
}
}
}
As you can see, I'm trying to access the accounts/$uid/ from within "demo", it doesn't seem to work, what am I missing/what do I need to change?
Many thanks
UPDATE
The code in question not working is:
".read": "accounts.$uid === auth.uid"
I can't seem to access this part. It doesn't seem to get the current user's authentication status.
UPDATE
See attached screenshot for my attempt on using a predefined variable. I'm simply trying to get the auth status and I'm getting an error saying it's undefined?

The UID of the current user who is trying to access the data is available in auth.uid. If you're trying to ensure that a read of quotes is only allowed if the user has a document in the accounts node, you're looking for exists().
"website-quotes": {
".read": "root.child('accounts').child(auth.uid).exists()"
}

Related

Firebase Realtime Database Security Rules - How to get into second node

I am struggling with the security rules on the firebase realtime database. My database structure is as following:
On the first level you have Chats. On the second level there are the Chat partners (a concatenated string with user IDs of chat partners). On the third level you have the messages. And on the last level there are the variables datetime, userid and message.
My question is, how can I get into the second child node, e.g. check if the auth.uid is within the concataneted string. My idea was to give the users read access, if the userid is within the chatpartners string, to ensure that only the chatpartners can read their messages. Or is this a thinking error?
I have tryid a lot of things, however no success:
"Chats":{
".read": "root.child('Chats').val().contains('auth.uid')"
}
#Update
{
"rules": {
"Chats": {
"$chatid": {
".read": "$chatid.contains(auth.uid)",
".write": "auth != null"
}
},
"Suchencards": {
".read": "true",
".write": "auth != null"
},
"UserData": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
I am using the playground on firebase console to check if I get true or false, however in that case I get false.
#Update 2
Screen1
Screen2
You can only access data in your rules if you know the exact path to that data, so you won't be able to access all chats from a rule on /Chats. Trying to do so typically means that you're trying to define your rules on the wrong level.
For example, if you want to allow a user to read a specific child of Chats, you'll need to define rules on that level:
"Chats":{
"$chatid": {
".read": "$chatid.contains(auth.uid)"
}
}
While the above will work for accessing a specific room, you will not be able to use this to query for all chat rooms that a user has access to (as Firebase queries don't support a "contains" operation). Have a look at the userChatrooms node in my answer here for a better model for tracking the chat rooms for a user: Best way to manage Chat channels in Firebase

how to set different rules for a path and its child in firebase?

I'm developing an application which needs to keep data separate for each user, which only they can access.
I know how this can be done with the following code:
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
But how can a new user be added if /users path is inaccessible?
If I set rules for /users path, it will cascade down to each uid path.
If we can set different rules for parent and child in some way, that could solve this problem.
Is this possible and secure? or please suggest another way to add users.
Still a beginner in firebase, please help.

Firebase auth database rules

I am working on the app that I need to connect to the dev firebase.
This firebase has database rules as follows:
"rules": {
// no read access at root level
".read": "auth.uid === 'emailaddressgmailcom'",
".write": false,
What I cannot understand is how auth.uid is specified to be an exact email address?
As far as I tried I only get unique uid provided by Google. (set of numbers and letters)
Hence I can never pass the auth to read from the database, unless I specify my exact uid given by Google in the databse rules, which is not an option because there will be another user who needs an access to db and I do not know his uid.
auth is one of the predefined variables.
By doing auth.uid, you get the user id ("guaranteed to be unique across all providers").
You need, in your Security Rules to use it to defined the access rights of a given user to one or more given resources, as explained here in the doc.
You could compare it to a fixed value, if a certain resource shall be read by a unique user:
".read": "auth.uid === 'HGH656675FHGFGHF3454'"
but usually you compare it to some parts of the path of the node/resource you want to protect, like for example:
{
"rules": {
"users": {
"$user_id": {
// grants write access to the owner of this user account
// whose uid must exactly match the key ($user_id)
".write": "$user_id === auth.uid"
}
}
}
}
This is how you should do to solve your problem "there will be another user who needs an access to db and I do not know his uid".
I would suggest you read the entire section about RTDB Security Rules form more details: https://firebase.google.com/docs/database/security
Please try below rules
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
// These rules grant access to a node matching the authenticated
// user's ID from the Firebase auth token

Firebase database structure with UID and database rules

Github repo https://github.com/JesseSoldat/Around-The-World-NG2-Firebase
Firebase JSON data exported to a file is in the repo FIREBASE_DATA.json
I have been trying to figure out the firebase database rule. I have read many articles and they all say that I need to do something like this
{
"rules": {
"locations": {
"$uid": {
".read": "true",
".write": "$uid === auth.uid"
}
},
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
I have structured my data with two directories
locations READ - all users WRITE - only the user that owns this data
users READ / WRITE - only the user that owns this data
When I set these rules my currently logged in user does not see their data anymore.
DATABASE
my format for saving users/${this.uid}/stories
I was using the UID as a way to make each user unique in the database.
ERROR MESSAGE from Firebase
Error: permission_denied at /users/HBTaJt057Bf63oS771gah1allYe2/stories: Client doesn't have permission to access the desired data.
I am not sure if I don't understand the concept or if I am missing some minor detail. Any ideas would be truly appreciated.
Regards,
Jesse

Can't get data from firebase. Authorization denied

I'm still starting out with firebase and i'm using angularfire to connect.
I was able to do the authentication successfully using google as a provider and I logged in using my account and got back my user details including uid & image, however, when I attempt to retrieve any data I get: permission_denied at /series: Client doesn't have permission to access the desired data. I also tried the simulator and got the same issue.
Here's my database:
My rules:
The data I entered in the simulator. I got the uid after signing in using google in the app:
And the result after using the simulator:
Here's where I got my UID from: (The authentication tab)
What am I supposed to be doing but not doing?
Finally found the answer. As cartant wrote
there are no read permissions granted, as .read defaults to false
all I needed to do was to ".read": "auth != null"
So the new rules are:
{
"rules": {
"series": {
".read": "auth != null", << THAT WAS MISSING
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}

Resources