Here is very simple rule for users:
{
"rules": {
"users": {
".read": true,
"$userId": {
".write": "auth.uid === $userId"
}
}
}
}
Of course it's not working when we want to create new user, and here is my question, how to create rule which will be checking if new key in users path will be the same as auth.uid?
Update
I need something like this line ".write": "auth.uid === $userId" below ".read": true but here is impossible because it wouldn't see $userId variable.
In my case this should work:
Location: /users
Data: { "user1" : { "name": tester" } }
UID: user1
but this shouldn't:
Location: /users
Data: { "user1" : { "name": tester" } }
UID: user2
{
"rules": {
"users": {
".read": true,
".write": "newData.hasChild(auth.uid) || data.hasChild(auth.uid)",
"$userId": {
".write": "auth.uid === $userId"
}
}
}
}
Related
I made a chat application using firebase realtime database. Users can send private messages to each other. How should the rules part be? I keep getting emails from Firebase that the rules are not reliable.
This is my firebase Collections:
This is my firebase Rules:
{
"rules": {
".read": "auth.uid!=null",
".write": "auth.uid!=null",
}
}
Only an authenticated admin user can read and write their own admin-user data:
{
"rules": {
"admin-users": {
"$userId": {
".read" : "auth.uid === $userId",
".write": "auth.uid === $userId"
}
}
}
}
Or:
{
"rules": {
"admin-users": {
"$user": {
".read" : "data.child('userUid').val() === auth.uid",
".write": "data.child('userUid').val() === auth.uid"
}
}
}
}
An authenticated user can read all data under Users.
An authenticated user can can only update their own data except the 'userUid' field. Can only update the 'userUid' field if it is a new document creation ('!data.exists()') e.g when it is a signup/register.
An authenticated admin can read and write all the data in Users including the 'userUid' field.
{
"rules": {
"users": {
".read": "auth !== null",
"$userId": {
"userId": {
".write": "root.child('admin-users').child(auth.uid).exists() || !data.exists()"
},
"$other_fields": {
".write": "$userId === auth.uid || root.child('admin-users').child(auth.uid).exists()"
}
}
}
}}
Only Admins can read and write everything in under Chats
Authenticated users can read chat messages in which their userUid matches either 'senderId' or 'receiverId'
Authenticated users can write/update a message only if their userUid matches 'senderId'.
{
"rules": {
"chats": {
".read": "root.child('admin-users').hasChild(auth.uid)",
".write": "root.child('admin-users').hasChild(auth.uid)",
"$chat": {
"$message": {
".read": "auth !== null && data.child('receiverId').val() === auth.uid || data.child('senderId').val() === auth.uid",
".write": "auth !== null && !data.exists() || data.child('senderId').val() === auth.uid"
}
}
}
}}
These sample rules are just to give guidance on how security rules work. You can create different rules that can work as well with your use case. See link for more details https://firebase.google.com/docs/rules/insecure-rules
https://firebase.google.com/docs/database/security/core-syntax
My Firebase Database structures is as follows:
{
"accounts" : {
"API_Keys" : {
"Unique ID over here" : {
"api_key" : "None",
}
}
},
"users" : {
"Unique UID over here" : {
"email" : "abc#gmail.com",
"username": "abc",
"age": "18"
},
}
}
I have implemented the following security rules for this.
{
"rules": {
"accounts": {
"API_Keys":{
"$uid":{
".read": "$uid === auth.uid && auth != null ",
".write": "$uid === auth.uid && auth != null"
}
}
},
"users": {
"$uid":{
".read": "$uid === auth.uid && auth != null ",
".write": "$uid === auth.uid && auth != null"
}
}
}
}
The user is going to link in his personal details and also an API Key. No user should be allowed to access any one else's keys somehow. Are the above rules satisfactory for this? Am i missing something?
It looks OK to me, though usually you reverse the order of the test to "auth != null && auth.uid == $uid", as seen in the documentation. You can test for yourself using the rules simulator in the Firebase console.
I just start working with firebase and im working on a project that user can Mark clinic appointments so i add some rules on firabase. Only the owner can read and write his own appointments.
I can write to firabase with no problem, but i cant read from it.
this is my code:
this is how i fetch th data
Firebase ref = new Firebase(Config.FIREBASE_URL).child("Consultas");
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
//Getting the data from snapshot
Consultas consulta2 = postSnapshot.getValue(Consultas.class);
String consulta1 = "Consulta de: "+consulta2.getNomeconsulta()+"\n";
String medico1 = "Com o Médico: "+consulta2.getNomemedico()+"\n";
String data1 = "Marcada para: "+consulta2.getHorario()+"\n\n";
String time = "Marcada para: "+consulta2.getTime()+"\n\n";
textView1.setText(consulta1);
textView2.setText(medico1);
textView3.setText(data1);
textView4.setText(time);
progressBar.setVisibility(View.GONE);
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
System.out.println("The read failed: " + firebaseError.getMessage());
}
});
This are my rules on firebase
{
"rules": {
// User profiles are only readable/writable by the user who owns it
"users": {
"$UID": {
".read": "auth.uid == $UID",
".write": "auth.uid == $UID"
}
},
// Posts can be read by the user who owns it/ written by the user who owns it.
"Consultas": {
"$UID": {
".read": "auth.uid == $UID",
".write": "auth.uid == $UID"
}
}
}
}
Thanks
FirebaseRules user === to equal values, you should change your code to:
{
"rules": {
// User profiles are only readable/writable by the user who owns it
"users": {
"$UID": {
".read": "auth.uid === $UID",
".write": "auth.uid === $UID",
}
},
// Posts can be read by the user who owns it/ written by the user who owns it.
"Consultas": {
"$UID": {
".read": "auth.uid === $UID",
".write": "auth.uid === $UID",
}
}
}
}
You can read more about it in the official documentation
Structure:
{
"accounts" : {
"JGeRgwAUBM..." : {
"active" : true,
"created" : 1468406951438,
"key" : "JGeRgwAUBM..."
}
}
Rules:
{
"rules": {
".read": false,
".write": false,
"accounts": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
Goal:
Instead of using the auth.uid as key for the data, I would rather prefer to use the generated key from push().getKey()
{
"accounts" : {
"theKeyIGetFrom: push().getKey()" : {
"active" : true,
"created" : 1468406951438,
"auth_uid" : "JGeRgwAUBM..."
}
}
Looking for the rule set for something like this:
{
"rules": {
".read": false,
".write": false,
"accounts": {
"$key": {
".read": "$key.auth_uid === auth.uid",
".write": "$key.auth_uid === auth.uid"
}
}
}
}
Answering your question, you will be able to achieve the rules you want with the rules bellow.
{
"rules": {
"accounts": {
"$key": {
".read": "data.child(auth_uid).val() === auth.uid",
".write": "data.child(auth_uid).val() === auth.uid"
}
}
}
}
But keep in mind that, to retrieve and write data, you would need to already know the $key's since you wont be able to get any data by accessing /accounts. Thats beacause you don't have read/write rules to access the specific /accounts branch.
If it was in my hands I would prefer going with your current /accounts/uid solution. You would always be easly able to retrieve users data since you could get the current authenticated user uid.
My firebase database is something like this:-
these are the security rules i have written but when i use them in simulator they validate just fine, but when used in code, give permission denied error
{
"rules": {
"jokes" : {
"textjokes" : {
".read" : true,
".write": "auth != null"
}
},
"users": {
"$uid": {
".write": "$uid == auth.uid"
}
},
"userslikelist": {
"$uid": {
".write": "$uid == auth.uid"
}
}
}
}
I get error:-
/userslikelist/qzCqJph6XcZbiIpbDKTTxwjRHrh1/-KK850oXwPnOvxan1xNG failed: FirebaseError: Permission denied
/jokes/textjokes/MISC-0-01/likeCount failed: FirebaseError: Permission denied
My code:-
Firebase ref = new Firebase("https://xxxxxxxxx.firebaseio.com/userslikelist/" + mAuth.getCurrentUser().getUid());
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
if(!likedMap.containsKey(postSnapshot.getKey())){
likedMap.put(postSnapshot.getKey(), postSnapshot.getValue(String.class));
}
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
I dont get it. what am i doing wrong?
Updated Code:-
{
"rules": {
"jokes": {
"textjokes": {
".read": true,
".write": "auth != null"
}
},
"users": {
"$uid": {
".write": "$uid == auth.uid"
}
},
"userslikelist": {
"$uid": {
".read": "$uid == auth.uid",
".write": "$uid == auth.uid"
}
}
}
}
You are not giving read access to /userslikelist/userId so you wont be able to get dataSnapshot on your onDataChange.
Make sure to set a read permission on the /userslikelist/userId level.
{
"rules": {
"jokes" : {
"textjokes" : {
".read" : true,
".write": "auth != null"
}
},
"users": {
"$uid": {
".write": "$uid == auth.uid"
}
},
"userslikelist": {
"$uid": {
".read": "$uid == auth.uid", //do whatever logic you need here
".write": "$uid == auth.uid"
}
}
}
}
For anyone else who is having this problem. The issue here was that i was using the legacy firebase api methods to set values and read from database. I changed the method of updating to use the new google firebase system as used in this example and now i can update the database.
https://github.com/firebase/quickstart-android/blob/master/database/app/src/main/java/com/google/firebase/quickstart/database/NewPostActivity.java#L39-L39