Home > Software engineering >  RealtimeDB index data by key
RealtimeDB index data by key

Time:10-01

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.

CodePudding user response:

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

CodePudding user response:

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.

  • Related