I have written some delete queries for a Realtime Database in Firebase, but keep running into issues due to a lack of indexing.
Here is an example of the data structure for one of the collections:
"followers": {
"user_id1": {
"user_ida": {
"field1": "string val",
"field2": true,
"user_id": "user_ida"
},
"user_idb": {
"field1": "string val",
"field2": false,
"user_id": "user_idb"
}
}
"user_id2": {
"user_idc": {
"field1": "string val",
"field2": true,
"user_id": "user_idc"
},
"user_idd": {
"field1": "string val",
"field2": false,
"user_id": "user_idd"
}
}
}
I want to query the collection by the nested user_ids, so that I can delete users from the lists that are no longer in our system. In my staging environment, the query works, and looks like this::
const userId = 'my_user_id_input';
const rt_ref = await app.database().ref('followers')
.orderByChild(`${userId}/user_id`)
.equalTo(userId)
const rt_proc = new BatchProcessor(rt_ref);
const rt_proms = [];
await rt_proc.forEach(key_id => {
console.log(`key_id = ${key_id}`);
rt_proms.push(app.database()
.ref(collectionName)
.child(key_id)
.child(userId)
.remove()
.then(() => println(` Successfully deleted user_id from Realtime "followers" where parent_id was ${key_id}`))
.catch((err) => {
println(` Error deleting Realtime "followers" for parent ${key_id} where ${userId} is child id: ${err}`);
}));
});
return Promise.all(rt_proms);
However ... because part of the query is dynamic -- ${userId}/user_id
-- this results in a warning to add an ".indexOn" rule to my followers collection in the Realtime database::
@firebase/database: FIREBASE WARNING: Using an unspecified index. Your data will be downloaded and filtered on the client. Consider adding ".indexOn": "my_user_id_input/user_id" at /followers to your security rules for better performance.
I've tried throwing everything at this in the Rules, but I've not been able to get anything to work. I'm stumped. Do I need to structure my query differently?
Here's what I've got at the moment in the Rules for this collection:
/* NOTE: FIGURE OUT INDEX FOR NESTED USER_ID! */
"followers": {
"$followed_id": {
"$follower_id": {
".write": "(auth != null)",
".indexOn": ["user_id", ".value"]
},
".indexOn": [
"timestamp",
"user_name",
"user_id",
".value"
]
},
".read": "true",
".indexOn": ["user_id", ".value"]
},
Granted, there are way too many "indexOn" entries in that collection, but I'm just trying as much as I can to see what will work.
I need to have this index to work, because we have a large amount of data in our PRODUCTION database, and this code just times out when it is run there :(.
Is there a solution for what I am trying to accomplish?