Permission denied when writing data in firebase database - android

I'm developing one small demo project which uses Firebase Auth and Database.
I have the following rule configured for my firebase database
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
Through this rule, I want an authenticated user to have a read and write access for their data only.
Below is the java code which is trying to save data.
DatabaseReference databaseReference= FirebaseDatabase.getInstance().getReference().child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("basic");
{
DemoModel demoModel=new DemoModel();
demoModel.setId(databaseReference.push().getKey());
demoModel.setUser("demoUser"); databaseReference.child(demoModel.getId()).setValue(demoModel).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
Toast.makeText(DemoActivity.this, Constants.SUCCESSFUL, Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(DemoActivity.this, Constants.FAILED, Toast.LENGTH_SHORT).show();
}
}
});
}
Error I'm getting: W/RepoOperation: setValue at /xgjCUqcasda444WkgZFHTNRUB3/basic/-Lywe44rft566hhyYYfDS failed: DatabaseError: Permission denied
W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
My database looks like:
demoProject-dd4568
xgjCUqcasda444WkgZFHTNRUB3
-basic
-LE3gdfdffdfaza
id:"-LE3gdfdffdfaza"
user: "asdasd"
Where I'm going wrong. I don't have much clue. when I change the rule to
{
"rules": {
".read":"auth != null",
".write":"auth != null"
}
}
it works fine. but it's not secure then.

Your rules don't match your database structure at all. Your rules are protecting child nodes under users, but you don't have a users node in your database.
You should probably be changing the location of the write to include users in the path.
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference root = FirebaseDatabase.getInstance().getReference();
//providing uid
DatabaseReference ref = root.child("users").child(uid).child("basic");

Related

when write to the database,database is still empty after registering.how to store data in my database correctly?

I'm writing to the Firebase realtime database. How to write to the database correctly?
Where is no errors found. But I changed dependencies of adding the realtime database to the app from com.google.firebase:firebase-database:16.0.1 to com.google.firebase:firebase-database:16.0.6.
This is the defined variable
private DatabaseReference mDatabase;
this is my register activity code part
private void register_user (final String displayName, String email, String password){
mAuth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
FirebaseUser current_user = FirebaseAuth.getInstance().getCurrentUser();
String uid = current_user.getUid();
mDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(uid);
HashMap<String,String> userMap = new HashMap<>();
userMap.put("name",displayName);
userMap.put("status","Hey there I am using ChatApp");
userMap.put("image","default");
userMap.put("thumb_image","default");
mDatabase.setValue(userMap);
} else {
mRegProgress.hide();
Toast.makeText(RegisterActivity.this, "Couldn't Sign in.Please Check and Try Again", Toast.LENGTH_LONG).show();
}
}
});
}
data entries should store in the database
Default security rules of Firebase Realtime Database rejects read and write. So you need to check and change security rules in firebase console.
Change the security rules into
{
"rules": {
"Users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
For more security options checkout the firebase docs

Firebase Security Permissions

I'm having trouble with a user who is trying to access someone else's email. I'm getting E/ContactsFragment.java: Finding email failed. DatabaseError: Permission denied. It's also worth noting that the email gets checked before going into the database and also the email that I inputted is the same as the one in the database.
Basically, what I'm trying to do is for user1 to find the user2's email. From there, I will do something with the email.
{
"rules": {
"users":{
".indexOn": ["email"],
"$uid":{
".read": "auth !== null",
"email":{
".write": "auth !== null && $uid === auth.uid",
".validate": "newData.isString()"
}
}
}
}
}
Here's my data structure:
Here's my code that is trying to access the email:
final String TAG = "ContactsFragment.java";
FirebaseDatabase.getInstance().getReference().child("users").orderByChild("email").equalTo(email).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// some code
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG,"Finding email failed. " + databaseError);
}
});
How can I fix it? Am I missing something important?
Currently, your rules are only granting read access to children under the /users node, but not the /users node itself, which will deny them from querying the list.
If you move your .read rule outside of the $uid child, it will allow users to query the the /users list node:
{
"rules": {
"users":{
".indexOn": ["email"],
".read": "auth !== null",
"$uid":{
"email":{
".write": "auth !== null && $uid === auth.uid",
".validate": "newData.isString()"
}
}
}
}
}
Queries are attached to the list node rather than child nodes under the list, so the .read permission needs to be granted on the list itself. For example, your query is being attached to the /users node:
FirebaseDatabase.getInstance().getReference().child("users").orderByChild("email").equalTo(email)[...]
This is because rules are applied in an atomic manner, and therefore a .read rule at a deep path will not allow access to a shallower path.

Can't write to Firebase after changing rules

Using the default rules for writing to my real-time database:
{
"rules": {
".read": "true",
".write": "true"
}
}
I am able to successfully save data to the database:
The code from my Android app looked like this:
DatabaseReference mDatabaseReference;
mDatabaseReference = DatabaseReference.getInstance().getReference();
...
mDatabaseReference.child("user").child(user.getUid()).setValue(user);
But to allow signed in users (email and password auth) to access only their own data, I found this Firebase - How to write/read data per user after authentication. The answer uses a class Firebase that I can't seem to find anywhere. So I changed the rules to this:
{
"rules": {
"users": {
"$uid": {
".write": "$uid === auth.uid",
".read": "$uid === auth.uid"
}
}
}
}
with a little modification to my java code:
DatabaseReference mDatabaseReference, databaseReference;
...
mDatabaseReference = FirebaseDatabase.getInstance().getReference();
databaseReference = mDatabaseReference.child("user");
...
databaseReference.setValue(user); //user is a POJO
After deleting the old entries in my database and re-running my app, nothing happens when I try to save a new user.What am I missing?
In your rules, change users to user.
The name of the child in your Firebase rules
must match the name of the child in your java code.
Images added for clarity

Android Firebase Database Error: Permission denied

I am working on an android project that requires user email and pwd authentication. The details are stored in the firebase database.The problem occurs whenever I try logging in again with the email and password. In my logcat the error message is:
W/SyncTree: Listen at / failed: DatabaseError: Permission denied
Take a look at my code below:
public class LoginUser extends AppCompatActivity {
private RelativeLayout relativeLayout;
private EditText et_email, et_password;
private Button loginBtn;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener authStateListener;
private DatabaseReference databaseReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_user);
mAuth = FirebaseAuth.getInstance();
databaseReference = FirebaseDatabase.getInstance().getReference();
databaseReference.keepSynced(true);
relativeLayout = (RelativeLayout) findViewById(R.id.activity_login_user);
et_email = (EditText) findViewById(R.id.emailField);
et_password = (EditText) findViewById(R.id.pwdField);
loginBtn = (Button) findViewById(R.id.loginBtn);
loginBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
initLogin();
}
});
authStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() != null){
initLogin();
}
else {
startActivity(new Intent(LoginUser.this,RegisterFireBase.class));
}
}
};
}
#Override
protected void onStart() {
super.onStart();
mAuth.addAuthStateListener(authStateListener);
}
#Override
protected void onStop() {
super.onStop();
if (mAuth != null){
mAuth.removeAuthStateListener(authStateListener);
}
}
private void initLogin() {
String email = et_email.getText().toString().trim();
String pass = et_password.getText().toString().trim();
if (!TextUtils.isEmpty(email) && !TextUtils.isEmpty(pass)){
mAuth.signInWithEmailAndPassword(email,pass).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
checkForUser();
}
});
}
else {
Toast.makeText(this, "Some fields are empty", Toast.LENGTH_SHORT).show();
}
}
private void checkForUser() {
final String userId = mAuth.getCurrentUser().getUid();
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild(userId)){
Intent loginIntent = new Intent(LoginUser.this, FireProfile.class);
loginIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(loginIntent);
Snackbar.make(relativeLayout,"Log In Successful",Snackbar.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
What could be causing this?
Possible reason could be : you dont have read and write access on your database.
For enabling read and write access :
Go to firebase console and enable read and write operations on your database.
Firebase Console -> Database(develop) -> RULES
{
"rules": {
".read": "true",
".write": "true"
}
}
Do not put you app public if this is not needed.
As described on google documentation you can do these rules on your firebase > database > rules
// 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"
}
}
}
}
or to let only authenticated users
// These rules require authentication
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
Letting an app public let anyone write and read your app... i don't think any app should use this like that.
Go to the Rules tab on your Database console. If you have not explicitly granted .read access to your user then permission will be denied.
This link is excellent in the Firebase doc:
https://firebase.google.com/docs/database/security/securing-data
These two notes on that page are of particular interest:
Note: Access is disallowed by default. If no .write or .read rule is specified at or above a path, access will be denied.
Note: Shallower security rules override rules at deeper paths. Child rules can only grant additional privileges to what parent nodes have already declared. They cannot revoke a read or write privilege.
Review the node where permission is being denied and use the Simulator on the Rules tab in order to test your rules for different user security contexts (non-authenticated, authenticated, etc.)
Do some changes on firebase database.
go to firebase -> Database -> rules
{
"rules":
{
".read": true,
".write": true
}
}
Most answers are simply suggesting making the database access to anyone to read and edit. This may be acceptable for rough testing, but certainly not for anything serious.
Google Firebase allows configuration to allow and deny access. Read the official documentation here:
https://firebase.google.com/docs/rules/basics#realtime-database
(Make sure to select the right type of Firebase database)
For anything requiring authentication, you will need to set up Firebase auth: https://firebase.google.com/docs/auth
Here are some basic examples:
No access (default)
{
"rules": {
".read": false,
".write": false
}
}
Authenticated Users Only
{
"rules": {
".read": "auth.uid != null",
".write": "auth.uid != null"
}
}
Read Public, Write by Owner Only
{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data
"rules": {
"some_path": {
"$uid": {
".read": true,
// or ".read": "auth.uid != null" for only authenticated users
".write": "auth.uid == $uid"
}
}
}
}
Please try to change your firebase rules like below I faced this problem previously.
My problem was in database rules:
{
"rules": {
".read": "true",
".write": "true"
}
}
the problem is that the firebase database has two projects with the same name and one of the project's rules are not even enabled
So see on all projects once
Go to firebase console and enable read and write operations on your database.
Firebase Console -> Database(develop) -> RULES
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
if you are using the old version add the following rule,
{
"rules": {
".read": "true",
".write": "true"
}
}

Creating a new object in Firebase on Android

Following the official documentation, I want to store a new object (an instance of my Order class) on Firebase, and I want it to create a new key for me. This is what I'm doing:
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference orders = database.getReference("orders");
orders.push().setValue(order);
But nothing shows up from the console. Do I need to create the orders key in advance? I cannot create if manually from the console, because it appears that empty keys aren't valid.
The Order class is as follows:
public class Order {
private final ArrayList<OrderItem> orderItems = new ArrayList<>();
public ArrayList<OrderItem> getOrderItems() {
return orderItems;
}
public void addOrderItem(OrderItem orderItem) {
orderItems.add(orderItem);
}
}
Edit
Based on the comments, I checked the error I get:
Permission denied
But my access rules are:
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
So the rule should apply only to the users key, not to the orders one. For other keys, the default rules should apply:
The default rules require Authentication. They allow full read and write access to authenticated users of your app.
My user is authenticated, so why this is not working in my case? How can I ensure that the user is authenticated properly?
In any case, changing the access rules to:
{
"rules": {
"orders": {
".read": "auth != null",
".write": "auth != null"
},
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
Doesn't solve the problem.
Firebase does not support serializing Arraylists. You should use a List or Map instead.
The support Datatypes are:
String
Long
Double
Boolean
Map<String, Object>
List<Object>
You are confusing the default rules for your Database with the default rules that apply to a certain access:
Note: Access is disallowed by default. If no .write or .read rule is specified at or above a path, access will be denied.
Offical Firebase Documentation
To check if the user is signed in you can use this code snippet from the Docs:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
// User is signed in
} else {
// No user is signed in
}
Or you can use a listener to get informed about changes with the AuthState:
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
} else {
// User is signed out
Log.d(TAG, "onAuthStateChanged:signed_out");
}
// ...
}
};

Categories

Resources