When running my Android app using a Firebase Realtime Database I get the following warning:
Using an unspecified index. Consider adding ".indexOn" ... to your security and Firebase Database rules for better performance
I totally understand the warning. But I don't know how to make it better. I really want to query only on indexed fields!
This is my DB:
{
"groupUsers" : {
"g1" : {
"u1" : "admin"
},
"g2" : {
"u1" : "admin",
"u2" : "readonly"
}
},
"groups" : {
"g1" : {
"areas" : {
"a1" : {
"groupId" : "g1",
"name" : "My Group"
}
},
"interests" : {
"i1" : {
"groupId" : "g1",
"name" : "My Interest"
}
},
"points" : {
"p1" : {
"address" : "First Street",
"areaId" : "a1",
"groupId" : "g1",
"latitude" : -25,
"longitude" : -55,
"name" : "Harry"
}
},
"properties" : {
"name" : "My Group Name"
},
"waypoints" : {
"w1" : {
"areaId" : "a1",
"groupId" : "g1"
}
}
}
}
"users" : {
"u1" : {
"email" : "some@domain.com",
"firstName" : "Peter",
"lastName" : "Smith"
},
"u2" : {
"email" : "other@email.com",
"firstName" : "John",
"lastName" : "Wayne"
}
}
}
These are my security rules:
{
"rules": {
"groups": {
"$groupId": {
".read": "root.child('groupUsers').child($groupId).child(auth.uid).exists()",
".write": "! root.child('groupUsers').child($groupId).exists() || root.child('groupUsers').child($groupId).child(auth.uid).val() === 'admin'",
"$child": {
".write": "root.child('groupUsers').child($groupId).child(auth.uid).exists() && root.child('groupUsers').child($groupId).child(auth.uid).val() !== 'readonly' && ($child === 'points' || $child === 'visits')"
}
},
"areas": {
".indexOn": ["groupId", "name"]
},
"waypoints": {
".indexOn": ["groupId", "areaId", "sequenceNumber"]
},
"interests": {
".indexOn": ["groupId", "rank", "name"]
},
"points": {
".indexOn": ["groupId", "areaId", "name"]
},
"visits": {
".indexOn": ["groupId", "pointId", "interestId", "userId"]
}
},
"users": {
".read": "auth != null",
"$userId": {
".write": "auth != null && $userId === auth.uid && newData.val() != null",
".indexOn": ["email", "firstName", "lastName"]
}
},
"groupUsers": {
".read": "auth != null",
"$groupId": {
".write": "auth != null && (root.child('groupUsers').child($groupId).child(auth.uid).val() === 'admin' || !root.child('groupUsers').child($groupId).exists())"
}
}
}
}
The problem is the groupUser
structure. It has group keys as property names. I do not have a field to index on since I do not have a constant property name.
How to change the structure to make it possible that all fields are indexed and that all my rules still work?