I am new to Firebase. I authenticated the user using email and password -
final Firebase ref = new Firebase("https://app.firebaseio.com");
ref.authWithPassword("[email protected]", "password", new Firebase.AuthResultHandler() {
@Override
public void onAuthenticated(AuthData authData) {
System.out.println("User ID: " + authData.getUid());
getData(ref);
}
@Override
public void onAuthenticationError(FirebaseError firebaseError) {
}
});
But after authentication when I am reading the data, I am getting Permission Denied
.
private void getData(Query ref) {
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
System.out.println(snapshot.getValue());
}
@Override
public void onCancelled(FirebaseError firebaseError) {
System.out.println("The read failed: " + firebaseError.getMessage());
}
});
}
These are the Firebase rules.
{
"rules": {
"users": {
"$uid": {
".read": "auth !== null && auth.provider === 'password'"
}
}
}
}
Firebase's permission model only allows the user access to data that you explicitly give access to. Since in your security rules, you only give access to /users/$uid
, the user cannot read from root /
. The Firebase documentation covers this under "rules cascade".
You seem to want to use security rules to filter data, which is not possible with Firebase's security model. See the section "rules are not filters" in the Firebase documentation as well as these previous questions and answers:
The simplest solution is to allow read of the users
node:
{
"rules": {
"users": {
".read": "auth !== null && auth.provider === 'password'"
}
}
}
And then query on that level:
getData(ref.child("users"));
I got this exception using a slightly different approach to read from my database, but this is how I solved the issue.
First of all, my database rules looked liked this:
{
"rules": {
"student": {
"$uid": {
".write": "auth != null && auth.uid == $uid",
".read": "auth != null && auth.uid == $uid"
}
}
}
}
Earlier on, to write to to the student database, I used this code in my Activity:
mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
Log.e(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
} else {
// User is signed out
Log.e(TAG, "onAuthStateChanged:signed_out");
}
// ...
}
};
...
Student student = new Student();
student.setPhoneNumber("+23480547455343");
student.setCountryOfOrigin("Nigeria");
mDatabaseReference.child("student").child(user.getUid()).setValue(student).
addOnCompleteListener(DetailsCaptureActivity.this,
new OnCompleteListener<Void>() {
...
});
Notice how the child name (student) matches the child name in the firebase data rules?
Now to read the data of this user, I did this:
//Set up an AuthStateListener that responds to changes in the user's sign-in state:
mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
user = firebaseAuth.getCurrentUser();
if (user != null) {
databaseReference = firebaseDatabase.getReference().child("student").child(user.getUid());
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Student student = dataSnapshot.getValue(Student.class);
phoneNumberTextView.setText(student.getPhoneNumber());
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG, databaseError.getMessage());
}
});
} else {
Log.e(TAG, "onAuthStateChanged:signed_out");
}
}
};
I got the permission denied exception if I did only:
databaseReference = firebaseDatabase.getReference().child(user.getUid());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With