Firebase rules write fails while read succeeds - android

I have these rules in my real-time database and cannot figure out why only the .write rule fails, while the .read succeeds. Both the write rule and read rule are the same aside from ".write" and ".read" so if one works, shouldn't the other?
In the 'Users' node all users have a homesteadId value which I'm trying to make sure is == to the uid under the Homesteads node which they are trying to edit.
"Homesteads": {
"$uid": {
".write": "root.child('Users').child('auth.uid').child('homesteadId').val() == $uid"
,".read": "root.child('Users').child('auth.uid').child('homesteadId').val() == $uid"
}
}
The highlighted nodes in the image below are the ones I'm trying to compare to ensure they are equal in order to give read/write access to the user.
I've also noticed that loading the data in my app has slowed down as a result of the above read rule. Now when the user signs in the data doesn't show immediately in its recyclerview as it should, and requires closing the app and opening it again before the data is displayed (or navigating to another view in the app and returning). Do security rules like this affect database query performance?
Thanks!

Related

Firebase Security Rules for a data sharing app

I am working on a simple react-native To-do app with sharing features. I am using Firebase Storage for storage and sharing. However, I am a beginner to Firebase and couldn't understand how to proceed. My requirements are as follows
Each user can add/remove/edit their own database entry.
User A should be able to share some of their To-dos with User B. The share can be in either view or edit mode (exactly like a Google Drive file).
An option to permanently allow User B to see all future view or edit mode for any new to-dos. Basically, an option to allow or disallow User B to see the data.
My attempt:
Bullet 1 can be achieved simply by
// These rules grant access to a node matching the authenticated
// user's ID from the Firebase auth token
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
source
For Point 2 and Point 3, I plan to have a separate JSON file accessible by all the users. So when user A gives edit access to some of its data to User B, the JSON file for user B should be updated with A's uid. I am not able to write security rules for this because I am not aware if we can write rules to get data from a JSON file. Also, this method is not very good in my opinion, as some attacker may flood User B's JSON file with garbage entries and in fact can delete the existing entries also.
Any help to achieve this Google Drive-like sharing feature for Firebase storage will be appreciated. Thanks!
You can allow who can write or read particular path in rules
if your database looks something like this:-
your rule can look something like this:-
"rules": {
"$uid":{
"$todoid":{
"todoitem":{
".read":"$uid == auth.uid || data.parent().child('sharedwith').child(auth.uid).val() === 'editor' || data.parent().child('sharedwith').child(auth.uid).val() === 'editor'",
".write":"$uid == auth.uid || data.parent().child('sharedwith').child(auth.uid).val() === 'editor'"
}
}
}
}
you can follow this blog post to understand better:- https://firebase.googleblog.com/2016/10/group-security-in-firebase-database.html
Am glad that you are trying to work with Firebase Realtime Database Rules.
Firstly I guess you understood concept of rules in a different way. The rules in firebase is not built to have User specific data control. These rules are used to give certain data access to certain type of users
For example :
You can give R/W permission to specific child to the users who are only Authenticated. For the one who not authenticated we can restrict the access
Main motive of this Rules tab is to avoid Data breaching from a 3rd party access
To know more about firebase rules please watch video in the given. link
https://www.youtube.com/watch?v=PUBnlbjZFAI
You can also see this Documentation
https://firebase.google.com/docs/database/security

Setting a Role-Based Access Programmatically

I have developed an app on Android that uses the Firebase realtime database. aka multiple nodes in the DB store various data collected by my app. For Auth, email/password-based Sign-in and Sign-up are working properly. When I sign-up a new user the auth works but that new user then needs to be granted access to the firebase database nodes the app uses. My app needs to grant this new user access to the firebase database nodes required for app interaction.
In other words, how do I programmatically, via my app, change the firebase node-access/security rules in my app (when I currently only know how to change these via the Firebase browser UI)? I do not see methods in FirebaseAuth to do this. So, where do I go from here?
Also, obviously a new user of my app will not have my credentials but they must be able to add access for themselves to my existing firebase realtime database nodes. How do I this?
Here are the rules I have in place today (where my UID is my actual firebase UID):
{
"rules": {
".read": "auth.uid === my UID",
".write": "auth.uid === my UID"
}
}
I now understand I must set rules to allow all authenticated users to read write data in various nodes of my tree. I do not yet understand how to grant access by node and particularly by a specific uid-based node in a tree where there may be many UIDs for each user. As an example, if my tree is root (top), then messages, then a UID for each user, what is the syntax for an authorization rule that will allow the current user/UID read/write the data in only his/her UID under root, messages, his/her user UID?

Firebase android security

i am building a chat android app that allows users to chat where users can create account and use all the features. It's about to be completed but there's a problem, actually a question.
Is firebase on android safe ?
In my firebase database, i have created a rule as follow:
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
Now, this rule will reject any non authenticated users from accessing the data and pushing data or deleting any of it. But, when user creates an account on my chat app, he/she will be authenticated and my app will allow to make modifications. What if they reversed engineered the app and changed some of the codes and pushed invalid datas or removed some of the values from database coz they are already authenticated ?? How can i prevent that ?
When user creates account in my app i use:
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(RegisterActivity.this, new OnCompleteListener<AuthResult>() {
This will create a new chat user for the app. So, user is creating his/her own account and they know the credentials and everything. I am so confused, how can i prevent them from editing my codes ?
You can't prevent malicious clients from executing whatever code they want against your Firebase project. Someone will always find a way to compromise your app at runtime on a device that you can't fully control.
The way to protect your data is through sophisticated security rules that:
Requires users to be authenticated (as you already have)
Decide which users can read and write to which locations in your database
Reject invalid data from being written
This requires a fair amount of thought and effort. You can start with the documentation to learn more.
Please also read this question on Quora for some more ideas.

Firebase admin and user account

I am building an Android app with firebase. Simple users would sign in and add data to the database. Users would be able to see only their own data. Then I need to have a single Admin account that sees all data in the firebase database. How should I go about it?
Did you secure your database in any way yet? If not, I recommend getting started with the documentation for Firebase security rules.
I typically secure my database as shown in the section on securing user data and then have a list of UIDs in the database for users with special permissions.
So with a JSON structure like this:
users
Power3000Uid: { ... }
PufUid: { ... }
admins
Power3000Uid: true
And security rules like this:
{
"rules": {
"users": {
"$uid": {
".read": "auth.uid == $uid || root.child('admins').child(auth.uid).exists()"
}
}
}
}
In words the .read rules is: "you can read this data if you're the owner of it, or if you're an admin". In the sample above this means that you can read anyone's data, but I can only read my own.
Depending on your exact needs, you'll need to repeat the admin-clause in various places in the database, or (what I usually do) just have it once at a high level in your JSON tree.

Firebase - should I recreate 'users'?

Sorry if this seems like a dumb question but the Firebase docs go round in circles.
I'm building an Android app and I'm authenticating users using mAuth.createUserWithEmailAndPassword documented here - https://firebase.google.com/docs/auth/android/start/
That's straightforward and I can set the username, email etc. and its all stored somewhere (I've no idea where as its not displayed in the Firebase console) BUT I'm confused about user based authentication - https://firebase.google.com/docs/database/security/user-security in the examples here (and elsewhere on the net) we see the rules starting with users
{
"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"
}
}
}
}
As far as I can see in the Firebase console there is no users child node in the database generated automatically from mAuth.createUserWithEmailAndPassword. So my question is should I create this or was a users child automatically created I just can't see it?
Its not a lot of work to implement an additional user child node and store user information there but it seems like a lot of duplication given that the authentication procedure has already stored the user information somewhere. The opposite way to ask this question is can I add the db write rules above and expect them to work if I have authenticated users but never added a users node in the db myself?
Why the docs don't spell this out is beyond me

Categories

Resources