0

I am using anonymous authentication with my app in which when the user opens the app he/she will be authenticated and the session will not end once the app closes.

I am having trouble figuring out how to code the read write rules. What I would like is for the user to be able to read and write their own entries without seeing any other users.

I have managed to authenticate the user as shown in the console logs below.

Firebase Structure:

"rounds" : {
    "-KBNYNvCAb-Wywq6yowW" : {
      "Arrow1" : "1",
      "Arrow2" : "1",
      "Arrow3" : "2",
      "Arrow4" : "2",
      "Arrow5" : "1",
      "Arrow6" : "1",
      "Bow" : "Hoyt",
      "Date" : 1456405827389,
      "Distance" : "10m",
      "RoundName" : "Dcedc",
      "Season" : "Indoor",
      "TotalScore" : 8,
      "UID" : "9ddc8eb2-6f1a-4c26-bac3-b5b473104bb6"

the current code in the read write is:

    {
  "rules": {
    "rounds": {
      "$rounds":{
        ".read": "auth.uid === data.child('UID').val()",
          ".write": "auth.uid === data.child('UID').val()"
        }
      }
    }
}

This only works in the simulator when I add the randomly generated table name in the url, for example

rounds/-KBNYNvCAb-Wywq6yowW

The controller to get the uid is in my controller here:

      app.controller('scoreCtrl', function($scope, roundInfo, equipmentStore){
      ref.onAuth(function(authData) {
            if (authData) {
      $scope.rounds = roundInfo;
      $scope.bow = roundInfo;
      $scope.round = roundInfo;
      $scope.date = new Date();
      $scope.addItem = function() {
        $scope.round.$add({
            "RoundName": roundInfo.name,
            "Distance": roundInfo.distance,
            "Season": roundInfo.season,
            "Date": this.date? this.date.getTime() : null,
            "Bow": $scope.bow.title.title,
            "Arrow1": roundInfo.arrow1,
            "Arrow2": roundInfo.arrow2,
            "Arrow3": roundInfo.arrow3,
            "Arrow4": roundInfo.arrow4,
            "Arrow5": roundInfo.arrow5,
            "Arrow6": roundInfo.arrow6,
            "TotalScore" : +roundInfo.arrow1 + +roundInfo.arrow2 + +roundInfo.arrow3 + +roundInfo.arrow4 + +roundInfo.arrow5 + +roundInfo.arrow6,
            "UID": authData.uid
                    });
                };
            }
      });
  });

Round Factory:

    app.factory('roundInfo', function($rootScope, $firebaseArray) {
    var roundRef = new Firebase("https://firebaseLink.firebaseio.com/rounds");
        roundInfo = {};
        roundInfo.name = '';
        roundInfo.bow = '';  
        roundInfo.date = '';
        roundInfo.distance = '';
        roundInfo.season = '';
        roundInfo.arrow1 = '';

            return $firebaseArray(roundRef);

});

The firebase authentication controllers:

        var ref = new Firebase("https://firebaseLink.firebaseio.com");
ref.authAnonymously(function(error, authData) {
  if (error) {
    console.log("Login Failed!", error);
  } else {
    console.log("Authenticated successfully with payload:", authData);
  }
  if (authData) {
    console.log("user logged in")
  } else {
    console.log("user logged out:")
  }    
});



    var ref = new Firebase("https://firebaseLink.firebaseio.com");
ref.onAuth(function(authData) {
  if (authData) {
    console.log("Authenticated with uid:", authData.uid);
  } else {
    console.log("Client unauthenticated.")
  }
});

The console logs confirm that the user has been authenticated:

0     450893   log      Client unauthenticated.
1     451712   log      Authenticated with uid:, 9ee68f25-d6ba-4902-9d83-329d0acf996e
2     451713   log      Authenticated successfully with payload:, [object Object
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
  • Also posted: https://groups.google.com/forum/#!topic/firebase-talk/9VRyKIepMPs and https://www.reddit.com/r/Firebase/comments/47qhu1/question_firebase_rules_help/ – Frank van Puffelen Feb 27 '16 at 11:04
  • Your updates make it clear: you're trying to query from `rounds`, but nobody has read permission on `rounds`. My answer explains why that is, but it's a duplicate of the ones I link to there. For example: http://stackoverflow.com/questions/31249956/firebase-rules-cannot-access-to-each-node – Frank van Puffelen Feb 28 '16 at 08:40

2 Answers2

1

Your question is missing some crucial information (such as what operation is failing), but I'm going to take an educated guess here.

You're most likely trying to read from rounds and aiming to get back only the children that the user has access to. Something like:

ref.child('rounds').on('child_added', function(snapshot) {
  ...
})

This is not how Firebase security rules work.

To be able to read or query a location, you must have read permission at that location.

The trap you've fallen for is covered under the section rules are not filters in the Firebase documentation.

So in your rules, since the user doesn't have read permission on rounds the read operation will fail. This is one of the reasons why it's often better to store the items under the user that owns them:

user_rounds
  "9ddc8eb2-6f1a-4c26-bac3-b5b473104bb6"
    "-KBNYNvCAb-Wywq6yowW": true
    ...

Some questions dealing with the exact same problem:

Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
0

Try adding read/write rules to the parent "rounds"

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