skip to Main Content

I have the following error while I try to query the members of my database:

FirebaseException ([firebase_database/index-not-defined] Index not defined, add ".indexOn": "36a72WVw4weQEoXfk3T9gCtOL9n2", for path "/members", to the rules

I am trying to check if there is already a chat with those members in my database. This is what I am executing:

final snapshot = await _database.ref().child("members").orderByChild(firstUserId).equalTo(true).get();

This is my DB structure

DB

I have been searching how to index by key but I haven’t found anything. Is there something I am doing wrong?
I hope you can help me thanks in advance.

2

Answers


  1. Indexes for keys are automatically created, but in this case you don’t even really need an index as you’re not querying on the key.

    The easiest way to do this sort of check is:

    final snapshot = await _database.ref().child("members").child(firstUserId).get();
    if (snapshot.value == true) {
      ...
    }
    

    So we’re not using a query here, but are instead always reading the snapshot to then check its value.

    The reason you can’t use a query is that it’d require an explicit/named index on every child node. For more on that, see my answer here: Firebase query if child of child contains a value

    Login or Signup to reply.
  2. When you’re using a structure that looks like this:

    Firebase-root
      |
      --- members
           |
           --- -ND81...kyPL
                 |
                 --- 36a7...L9n2: true
                 |
                 --- LLhw...vyP2: true
    

    Indeed you need a query since the second level (-ND81…kyPL) inside your database is dynamic. The problem with your approach is that each query you perform requires an index, which cannot be done, since you cannot create an index for each user that becomes a member. Besides that, creating an index cannot be made programmatically. You need to create it manually inside the Firebase console.

    It’s true that you can attach a listener to the members node and check if a particular UID exists inside the snapshot object that you get as a result. But in my opinion, this solution can be used with a small amount of data. If the number of members gets bigger, downloading the entire node and doing the verification on the client, isn’t a recommended option.

    Since I think that the member most likely corresponds to a group, an organization, or a user that created them, then most likely it’s best to have a node that has a static, known value. So if you’re allowed to change the database schema, I would recommend something like this:

    Firebase-root
      |
      --- members
           |
           --- $uid
                 |
                 --- 36a7...L9n2: true
                 |
                 --- LLhw...vyP2: true
    

    In this way you can simply check if a UID exists using:

    final snapshot = await _database.ref().child("members").child(uid).child(firstUserId).get();
    if (snapshot.value == true) {
        //Your logic.
    }
    

    But the UID node can be any other know ID.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search