155

I'm relatively new to coding and am having trouble.

I have this code to send data to firebase

app.userid = app.user.uid

var userRef = app.dataInfo.child(app.users);

var useridRef = userRef.child(app.userid);

useridRef.set({
  locations: "",
  theme: "",
  colorScheme: "",
  food: ""
});

However, I keep getting the error:

FIREBASE WARNING: set at /users/(GoogleID) failed: permission_denied 2016-05-23 22:52:42.707 firebase.js:227 Uncaught (in promise) Error: PERMISSION_DENIED: Permission denied(…)

When I try to look this up it talks about rules for Firebase, which seems to be in a language that I haven't learned yet (or it is just going over my head). Can someone explain what is causing the issue? I thought it was that I was asking for it to store email and user display name and you just weren't allowed to do this, but when I took those out I still had the same problem. Is there a way to avoid this error without setting the rules, or are rules something I can teach myself how to write in a day, or am I just way out of my league?

Thanks for any help!

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
Robert Prine
  • 2,633
  • 5
  • 14
  • 17

10 Answers10

313

By default the database in a project in the Firebase Console is only readable/writeable by administrative users (e.g. in Cloud Functions, or processes that use an Admin SDK). Users of the regular client-side SDKs can't access the database, unless you change the server-side security rules.


You can change the rules so that the database is only readable/writeable by authenticated users:

{
  "rules": {
    ".read": "auth != null",
    ".write": "auth != null"
  }
}

See the quickstart for the Firebase Database security rules.

But since you're not signing the user in from your code, the database denies you access to the data. To solve that you will either need to allow unauthenticated access to your database, or sign in the user before accessing the database.

Allow unauthenticated access to your database

The simplest workaround for the moment (until the tutorial gets updated) is to go into the Database panel in the console for you project, select the Rules tab and replace the contents with these rules:

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

This makes your new database readable and writeable by anyone who knows the database's URL. Be sure to secure your database again before you go into production, otherwise somebody is likely to start abusing it.

Sign in the user before accessing the database

For a (slightly) more time-consuming, but more secure, solution, call one of the signIn... methods of Firebase Authentication to ensure the user is signed in before accessing the database. The simplest way to do this is using anonymous authentication:

firebase.auth().signInAnonymously().catch(function(error) {
  // Handle Errors here.
  var errorCode = error.code;
  var errorMessage = error.message;
  // ...
});

And then attach your listeners when the sign-in is detected

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    // User is signed in.
    var isAnonymous = user.isAnonymous;
    var uid = user.uid;
    var userRef = app.dataInfo.child(app.users);
    
    var useridRef = userRef.child(app.userid);
    
    useridRef.set({
      locations: "",
      theme: "",
      colorScheme: "",
      food: ""
    });

  } else {
    // User is signed out.
    // ...
  }
  // ...
});
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • 1
    Thanks - used the insecure fix and [quoted your answer in a reply to a similar question](http://stackoverflow.com/a/43938055/123033) to progress past Firebase permission issues in this [Ember tutorial](https://emberway.io/a-gentle-introduction-to-ember-2-0-8ef1f378ee4). But where do we add the (secure) anonymous auth code? – Dave Everitt May 12 '17 at 12:47
  • 3
    OMG there goes an hour. I had this in there but the values were FALSE... I just overlooked it. Changed them to TRUE and bam, app is working like you'd think... – Andy Jul 17 '18 at 16:27
  • OMG, me fn too, couldnt figure out why they were failing on permissions when they were both already set to false (until i read your comment). duh, noob mistake., they should both be true when you are making it open to the public (reads). Thanks for pointing out your own error, you helped me figure it out. For the record I changed my rule to this: ".read": true and then it started working. – contractorwolf Oct 21 '18 at 03:32
  • @Andy Thanks man , same to me and seeing your comment just solved my prob ;) – Mahmudul Hasan Sohag Jan 15 '20 at 04:06
  • Also received 'permission denied' User access errors, but seems because the date on Firebase Database by Unix epoch and on Storage had expired today. But adding the auth rule to the Database allowed reading and writing again. (Note the error wasn't time-access denied, maybe Firebase could look into.) Thanks for the great work FB, SO, all of you devs! :) – verNsíon1 Nov 22 '22 at 14:54
92

I was facing similar issue and found out that this error was due to incorrect rules set for read/write operations for real time database. By default google firebase nowadays loads cloud store not real time database. We need to switch to real time and apply the correct rules.

enter image description here

As we can see it says cloud Firestore not real time database, once switched to correct database apply below rules:

{
   "rules": {
       ".read": true,
       ".write": true
     }
 }

Note:

Be careful with the rules. By setting read and write to true makes database vulnerable to praying eyes.

Read more:

https://firebase.google.com/docs/database/security

just-be-weird
  • 1,242
  • 9
  • 7
  • 4
    Damn UI ! I spent the whole day, figuring out why I have different rules... Ah... It was for "cloud firestore"... Thanks! – Alexey Vol Apr 06 '19 at 09:08
45

Go to the "Database" option you mentioned.

  1. There on the Blue Header you'll find a dropdown which says Cloud Firestore Beta
  2. Change it to "Realtime database"
  3. Go to Rules and set .write .read both to true

Copied from here.

Isuru
  • 30,617
  • 60
  • 187
  • 303
Ahmed Adewale
  • 2,943
  • 23
  • 19
  • 2
    I downvoted this because I believe it's bad advice. If a rookie asks how to make the front door of their shop open, you can't just recommend they remove the lock altogether. Disabling security rules can lead to a disaster, and potentially very expensive fines if user data is leaked (and most likely it will). – silviot Aug 13 '20 at 13:31
  • 1
    A rookie that was stuck here for days would consider my answer so helpful. I know how happy I am when I fix this now I'm helping people and you are downvoting @silviot a rookie is just learning nothing on the production – Ahmed Adewale Sep 06 '20 at 09:58
  • 2
    I see your point, and I totally agree with the spirit. Thing is, you didn't specify that in your answer. Had you included a word of caution I would have totally agreed. But you only mention the steps needed to remove security checks, without warning about the possibly unintended consequences. – silviot Sep 08 '20 at 14:17
9

Go to database, next to title there are 2 options:

Cloud Firestore, Realtime database

Select Realtime database and go to rules

Change rules to true.

M--
  • 25,431
  • 8
  • 61
  • 93
Jaywant Narwade
  • 145
  • 1
  • 4
  • 3
    I downvoted this because I believe it's bad advice. If a rookie asks how to make the front door of their shop open, you can't just recommend they remove the lock altogether. Disabling security rules can lead to a disaster, and potentially very expensive fines if user data is leaked (and most likely it will). Also, it's a duplicate of @ahmed-adewale's answer. – silviot Aug 13 '20 at 13:28
4
  1. Open firebase, select database on the left hand side.
  2. Now on the right hand side, select [Realtime database] from the drown and change the rules to:
{
  "rules": {
    ".read": true,
    ".write": true
  }
}
M--
  • 25,431
  • 8
  • 61
  • 93
  • 10
    This has already been said in the other answer. Also when you suggest this make sure to add a warning because this isn't save! – André Kool Sep 16 '18 at 21:49
4

OK, but you don`t want to open the whole realtime database! You need something like this.

{
  /* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */
  "rules": {
    ".read": "auth.uid !=null",
    ".write": "auth.uid !=null"
  }
}

or

{
  "rules": {
    "users": {
      "$uid": {
        ".write": "$uid === auth.uid"
      }
    }
  }
}
Yaser Darzi
  • 1,480
  • 12
  • 24
2

PermissionDenied can also appear if provided Firebase project ID is incorrect.

See this guide to check your project ID:

Firebase console: Click settings Project settings. The project ID is displayed in the top pane.

Voy
  • 5,286
  • 1
  • 49
  • 59
1

Another solution is to actually create or login the user automatically if you already have the credentials handy. Here is how I do it using Plain JS.

function loginToFirebase(callback)
{
    let email = 'xx@xx.com';
    let password = 'xxxxxxxxxxxxxx';
    let config =
    {
        apiKey: "xxx",
        authDomain: "xxxxx.firebaseapp.com",
        projectId: "xxx-xxx",
        databaseURL: "https://xxx-xxx.firebaseio.com",
        storageBucket: "gs://xx-xx.appspot.com",
    };

    if (!firebase.apps.length)
    {
        firebase.initializeApp(config);
    }

    let database = firebase.database();
    let storage = firebase.storage();

    loginFirebaseUser(email, password, callback);
}

function loginFirebaseUser(email, password, callback)
{
    console.log('Logging in Firebase User');

    firebase.auth().signInWithEmailAndPassword(email, password)
        .then(function ()
        {
            if (callback)
            {
                callback();
            }
        })
        .catch(function(login_error)
        {
            let loginErrorCode = login_error.code;
            let loginErrorMessage = login_error.message;

            console.log(loginErrorCode);
            console.log(loginErrorMessage);

            if (loginErrorCode === 'auth/user-not-found')
            {
                createFirebaseUser(email, password, callback)
            }
        });
}

function createFirebaseUser(email, password, callback)
{
    console.log('Creating Firebase User');

    firebase.auth().createUserWithEmailAndPassword(email, password)
        .then(function ()
        {
            if (callback)
            {
                callback();
            }
        })
        .catch(function(create_error)
        {
            let createErrorCode = create_error.code;
            let createErrorMessage = create_error.message;

            console.log(createErrorCode);
            console.log(createErrorMessage);
        });
}
Parampal Pooni
  • 2,958
  • 8
  • 34
  • 40
  • 2
    This is really bad security wise. – Mr. Arbitrary Jan 03 '20 at 12:15
  • Can you elaborate on that @Friedrick ? is it when run as local nodejs script? – Vincent Gerris Jul 12 '22 at 21:05
  • @VincentGerris The user's password really shouldn't leave their device without being hashed first. If you have it in plain text in your servers, that is really not great. – Mr. Arbitrary Jul 12 '22 at 23:34
  • @Friedrick I understand. but as long as the servers are secure, that ais often what will happen, unless some secure storage like vault from hashicorp is used. It's less bad on a client machine that is used to manipulate Firebase data, which I'm trying to do. So depends on the use and exposure. Worse would be it being in an Angular/Ionic project and ending up in the frontend code main,js! – Vincent Gerris Jul 13 '22 at 16:39
1

If you are attempting to reuse an old project in firebase, due to free account restrictions, then your database rules are probably outdated.

In my case, I was getting error 401 Unauthorized and it solved when I set both read and write rules equal to true.

Thanks for this great community!

Much respect from Brazil!

-2

i was also having the same problem. make sure that you are using the real-time database instead of the cloud. then change rules to allow access to all users as follows

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

by default the firestore database only allows admins to read and write from the database thus the read/write rules will be set to false.

about14sheep
  • 1,813
  • 1
  • 11
  • 18
Stycs07
  • 25
  • 3