Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase no index defined

I'm using Firebase to retrieve some data of Users. I need to retrieve only one User with (gameSearching = true).

My data looks like:

Users
|
|_____ John
|        |___ name: John Farmer
|        |___ gameSearching: true
|
|_____ James
|        |___ name: James Smith
|        |___ gameSearching: false
|
|_____ Barbara
         |___ name: Barbara Smith
         |___ gameSearching: true

I'm running this code:

setData(('Users/' + you + '/'), {gameSearching: true});

var ref = new Firebase("https://grootproject.firebaseio.com/Users");
var child = ref.orderByChild("gameSearching");
child.on("child_added", function (data) {
    var yourself = firebase.getAuth().password.email.split("@", 1)[0];
    data.forEach(
        function (childSnapshot) {
            if (childSnapshot[i].val().gameSearching == true && childSnapshot[i].key() != yourself) {
                var opponent = childSnapshot[i].key();

                setData(('Users/' + opponent + '/'), {gameSearching: false});
                setData(('Users/' + yourself + '/'), {gameSearching: false});
            }
        }
    );


});

Because 'data' has multiple values, I use 'data.forEach' to separate them. After that point I can set a 'return' on 'true' so I only will recieve one User with 'gameSearching: true'.

My firebase rules:

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

When I run this code I get the following error:

'Uncaught Error: No index defined for gameSearching'

I have searched for setting a index on 'gameSearching' using '.indexOn' but not with any succes. https://www.firebase.com/docs/security/guide/indexing-data.html

Does anyone have a example or a solution?


Edit:

I now got the following code:

var ref = new Firebase("https://grootproject.firebaseio.com/Users");
    ref.orderByChild("gameSearching").equalTo(true).limitToFirst(1).on("child_added", function (data) {
        var yourself = firebase.getAuth().password.email.split("@", 1)[0];

            var opponent = data.key();
            console.log(opponent);

            setData(('Users/' + opponent + '/'), {gameSearching: false});
            setData(('Users/' + yourself + '/'), {gameSearching: false});
            console.log('ja');
    });

I edited my rules of my firebase:

{
"rules": {
    ".read": true,
    ".write": true,
    "Users": {
  ".indexOn": "gameSearching"
}
}

}

The indexOn error wont show anymore, so that's great. But ref.orderByChild("gameSearching").equalTo(true).limitToFirst(1) will runs twice. I don't know how that's possible. I'm using limitToFirst(1)`, so I expect 1 child?

like image 474
Mr. Sam Avatar asked Dec 01 '22 15:12

Mr. Sam


1 Answers

Now that you added your rules, it is clear what is wrong there.

These are your current rules:

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

So you allow everyone read and write access on your entire Firebase and tell it to add an index on gameSearching. The problem is that you've defined your index at the top-level, instead of at the level where it needs to be in your Firebase.

This is your current data structure:

{
    "Score" : {
        "sam_lous" : {
            "score" : 2
        }
    },
    "Users" : {
        "hallo" : {
            "gameSearching" : true
        },
        "sam_lous" : {
            "gameSearching" : true
        },
        "test" : {
            "gameSearching" : false
        },
        "test2" : {
            "gameSearching" : true
        }
    }
}

The gameSearching property exists only under children of the Users node. So that is where you should define your .indexOn:

{
  "rules": {
    ".read": true,
    ".write": true,
    "Users": {
      ".indexOn": "gameSearching"
    }
  }
}

With that, your index should be created (in my experience it happens straight away when you save your rules) and the error/warning message should disappear. But to fix the behavior, you should also make the changes that I put in my other answer.

I have to admit that Firebase's documentation on indexing your data, could be clearer on where you define these .indexOn rules. If someone at Firebase is reading along, can you please add some better examples that highlight that .indexOn needs to be defined at the level where the data resides?

like image 76
Frank van Puffelen Avatar answered Dec 15 '22 17:12

Frank van Puffelen