javascriptfirebasefirebase-realtime-databasefirebase-security

Firebase Permission Denied


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!


Solution

  • 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.
        // ...
      }
      // ...
    });