Firebase .Indexon Dynamic Keys

How to write .indexOn for dynamic keys in firebase?

I guess you're looking for:

{
".read": true,
".write": true,
"rules": {
"Tasks": {
"$groupid": {
".indexOn": "date"
}
}
}
}

The Firebase documentation is usually a pretty good read. Spending an hour or less in the security guide, will ensure you have a better understanding of this and many other topics.

Firebase indexOn rules in unique keys

The solution to this is just better noSQL schema.

That query would be trying to filter all entities and check if userId is found.

In reality you would have to have a ref like userEntities, which would include all entity keys this user is a part of - and by those keys fetch this users entities.

One thing you must note, designing your database for firebase is sequrity rules. Sequrity rules ultimately decide can this type of query even be acceptable on the client side.
Example:

firebase.database().ref('entities').orderByChild('users/' + user.uid)

is a call to 'entities' root, not individually to 'entities/users/userId'. So if you would like to disable reads for all other entities but your own you must try to access

.ref('entities').child(entityId)

That is a thing not highlighted enough in anywhere.

Relational databases win this one IMO.

Firebase .indexOn dynamic key not working

You need to define indexes on the level where run the query. Right now you have it one level too low.

So it should be:

"conversations": {
"$conversationId":{
"users" :{
"userId": {".indexOn": ".value"}
}
}
}

Firebase .indexOn dynamic keys

For this type of query (and in general when you get into requiring adding indexes dynamically) you'll likely need to set up an inverted index. In your case:

{
"babies" : {
"-KQSVCXI-ZMz_lQ_Q906" : {
"name" : "Baby",
"parents" : {
"F0o8Gr5GC2SrakUYZpC20efcmk63" : true
}
},
"-KQSf4t9XQC3LnbsxLYS" : {
"name" : "Name2",
"parents" : {
"S6aO6Dx4lgg6anW9S9hu7EJrhVg1" : true
}
}
},
"parents": {
"F0o8Gr5GC2SrakUYZpC20efcmk63": {
"babies": {
"-KQSVCXI-ZMz_lQ_Q906": true
}
},
"S6aO6Dx4lgg6anW9S9hu7EJrhVg1": {
"babies": {
"-KQSf4t9XQC3LnbsxLYS": true
}
}
}
}

This type of bidirectional linking is fairly common in Firebase (and in many similar NoSQL databases).

How does .indexOn works with users and unique keys?

Firebase Realtime Database queries work on a flat list of the nodes under the location where you run the query. So in your case, the query considers the direct children of the mileage_maintenance node (which is just the node 1 in the screenshot).

You can have wildcards in your rules, like in your case:

{
"rules": {
".read": true,
".write": true,
"mileage_maintenance": {
"$id": {
"battery_and_cables":{
".indexOn": ["distance_traveled"]
}
}
}
}
}

As you can see, I added a $id level here for the 1 node. That now means that you have an index defined on each /mileage_maintenance/$id/battery_and_cables node for the distance_traveled property of each child node under that.

So with this index, you can query a specific /mileage_maintenance/$id/battery_and_cables path for the distance_traveled values. But you can't run a query on just /mileage_maintenance for all distance_traveled values under it.

If you need such a query, you will need to modify/augment your data model to allow it. For example, by introducing a flat list of distance_traveled nodes that you can then query:

"distance_traveled": {
"1000000": "1/battery_and_cables/-M01CT...1hMj"
}

Or

"distance_traveled": {
"1~battery_and_cables~-M01CT...1hMj": 1000000
}

Where the ~ in that last model is just a separate for the segments in that key, since / isn't allowed.

Also see:

  • Firebase Query Double Nested
  • Firebase query if child of child contains a value

Firebase realtime .indexOn

As suggested by Hristo Eftimov I change my way to stock the tags in order to have a better access. I did that by creating different table for tag that is more easy to access and doesn't need an particular index

Firebase .indexOn dynamic keys

Firebase .indexOn with complex DB structure

It seems fairly simple to add the requested index:

{
"rules": {
"users": {
".indexOn": ["kxSWLGDxpYgNQNFd3Q5WdoC9XFk2", "SjZLsTGckoc7ZsyGV3mmwc022J93", "mcOK5wVZoZYlFZZICXWYr3H81az2"]
}
}
}

More likely your concern is that it's not feasible to add these indexes manually, since you're generating the user IDs in your code.

Unfortunately there is no API to generate indexes.

Instead you'll need to model your data differently to allow the query that you want to do. In this case, you want to retrieve the conversations for a specific user. So you'll need to store the conversations for each specific user:

conversationsByUser {
"SjZLsTGckoc7ZsyGV3mmwc022J93": {
"-KS3Y9dMLXfs3FE4nlm7": true
},
"mcOK5wVZoZYlFZZICXWYr3H81az2": {
"-KS3Y9dMLXfs3FE4nlm7": true
}
}

It may at first seem inefficient to store this data multiple times, but it is very common when using NoSQL databases. And is really no different than if the database would auto-generate the indexes for you, except that you have to write the code to update the indexes yourself.



Related Topics



Leave a reply



Submit