Reputation: 324
I would like to know how to secure my rules. I tried to use auth.uid != null
in read and write.
But if a new user is trying to login or create new account it won't succeed and gives me permission denied.
I want to secure Users and restrict read for user himself and his data only:
I tried to use auth.uid != null
but already reg user won't be able to login, and new users can't create account. So I had to make it true for public write and read. Any solution?
cuz even auth.uid != null , authenticated user can read the entire data of all users not only himself
This is my rules copy:
{
"rules": {
".write": "root.child('Admins').child(auth.uid).exists()",
"Admins": {
".read": true,
".write": false
},
"Users": {
".read": true,
".write": true
},
"PrivateWork": {
".read": "auth.uid != null",
".write": false
},
"Likes": {
".read": "auth.uid != null",
".write": "auth.uid != null"
},
"Work": {
".read": "auth.uid != null",
".write": false
},
"videos": {
".read": "auth.uid != null",
".write": false
}
}
}
RegisterActivity:
//Check if num already exist
binding.continueBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (binding.phoneNumBox.getText().toString().isEmpty()) {
binding.phoneNumBox.setError(getString(R.string.please_enter_phone));
} else if (binding.phoneNumBox.getText().toString().length() < 6) {
binding.phoneNumBox.setError(getString(R.string.enter_valid_phone));
} else {
DatabaseReference userRef = FirebaseDatabase.getInstance().getReference("Users");
userRef.orderByChild("phoneNumber")
.equalTo(binding.phoneNumBox.getText().toString())
.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() != null) {
Toast.makeText(RegPhoneNumActivity.this, getString(R.string.already_exist), Toast.LENGTH_SHORT).show();
} else {
Intent intent = new Intent(RegPhoneNumActivity.this, OTPActivity.class);
intent.putExtra("phoneNumber", binding.phoneNumBox.getText().toString());
startActivity(intent);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
});
LoginActivity:
//Check if num already exist
binding.loginContinueBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (binding.loginPhoneNumBox.getText().toString().isEmpty()) {
binding.loginPhoneNumBox.setError(getString(R.string.please_enter_phone_numb));
} else if (binding.loginPhoneNumBox.getText().toString().length() <= 6) {
binding.loginPhoneNumBox.setError(getString(R.string.plaese_enter_valid_phone_num));
} else {
userRef.orderByChild("phoneNumber")
.equalTo(binding.loginPhoneNumBox.getText().toString())
.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() != null) {
Intent intent = new Intent(PhoneLoginActivity.this, LoginVerifyPhoneActivity.class);
intent.putExtra("phoneNumber", binding.loginPhoneNumBox.getText().toString());
startActivity(intent);
} else {
Toast.makeText(PhoneLoginActivity.this, getString(R.string.phone_num_doesnt_exist), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
});
Upvotes: 1
Views: 170
Reputation: 598728
To allow a user to only read their own data, you'll need to:
For the rules that means your Users
node becomes this:
"Users": {
"$uid": {
".read": "$uid === auth.uid"
}
},
And the code to access it then becomes:
userRef.child(FirebaseAuth.getInstance().getCurrentUser().getUID())
.addListenerForSingleValueEvent(new ValueEventListener() {
While it is also possible to check the phone number of the signed in user against the value of the node in the database, there too the user will have to be signed in already. If that is the case for you, check the documentation on securely querying data.
Upvotes: 1