0

I am confused with index rules in firebase. I have this database and I wanted to extract distance_traveled in battery_and_cables. The thing is, 1 is something like a userID set by the user itself so that will vary.

I used this code in pyrebase to extract the distance_traveled

db.child("mileage_maintenance").order_by_child("distance_traveled").get()

but I get

Index not defined, add ".indexOn": "distance_traveled", for path "/mileage_maintenance", to the rules

This is my database:

This is my database

Any my rules:

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

Is there any way you can go through the 1 and the push key to acquire the distance_traveled?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
fireblazer10
  • 25
  • 1
  • 10

1 Answers1

0

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:

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thank you! I now understand more about how indexing works. My problem now is how to call it out in pyrebase since `"error" : "Invalid path: Invalid token in path"` shows up when typing `/mileage_maintenance/$id/battery_and_cables`. Or am I understanding it wrong? – fireblazer10 Feb 15 '20 at 09:25
  • That sounds like you're trying to use `/` in the **key**, which is not allowed. That's why my last JSON snippet uses `~` as a separator. – Frank van Puffelen Feb 15 '20 at 15:52