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
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.