Estoy construyendo un proyecto y dentro de este proyecto tengo un chat uno a uno. Cada chat se almacena usando la base de datos en tiempo real de firebase (estoy usando la biblioteca react-native-firebase aquí).
Mi árbol de datos actualmente se ve así: 
Tenemos algo así: chat/{currentUserID}/{userID} luego los mensajes se almacenan aquí y se envían a la base de datos usando el método push() que genera automáticamente una ID.
Básicamente, lo que estoy tratando de hacer es limpiar un poco eliminando los mensajes de hace más de 7 días. Ya tengo la lógica para eso y lo estoy haciendo para otra parte de mi aplicación aquí:
const randomTestTimerDB = Date.now() - 1 admin.database() .ref('/publicChat') .orderByChild('timestamp') .endAt(randomTestTimerDB) .once('value') .then((snapshot) => { snapshot.forEach((snap) => { snap.ref.remove() }) })Esto funciona bien. Pero mi problema aquí es que estoy usando una función en la nube para eso, así que no puedo seguir mi árbol para llegar a ellos, ya que están anidados debajo y debajo de las ID que no tengo desde allí.
Sabiendo que dentro de la colección de chat podemos encontrar a todos los usuarios que ya enviaron un mensaje. Sabiendo también que cada uno de estos contiene los documentos (ID de usuario) de todos los usuarios con los que el usuario actual interactúa y debajo de cada uno de estos documentos, adjunto al documento de ID de usuario, finalmente tenemos todos los mensajes compartidos entre estos dos usuarios.
Traté de comunicarme con ellos de diferentes maneras, como llamar a la base de datos directamente dentro de un método forEach para graduar el snapshot.id de cada uno y tal vez obtener el child().val() después, pero parece que no funciona.
Aquí está el código de lo que probé hasta ahora:
admin.database() .ref('/chat') .once('value') .then((snapshot) => { snapshot.forEach((snap) => { if(snap.child().val().timestamp <= randomTestTimerDB) { snap.ref.remove() } }) }) admin.database() .ref('/chat') .once('value') .then((snapshot) => { snapshot.forEach((snap) => { admin.database().ref(`/chat/${snap.id}`).orderByChild('timestamp').endAt(randomTestTimerDB).once('value').then((snp) => { snp.forEach((eachSnp) => { eachSnp.ref.remove() }) }) }) })¿Cómo puedo tomar esos mensajes anidados de la manera más fácil posible? ¿Si esto es posible o debería pensar en otra forma de almacenar y organizar mi árbol de datos para que sea más fácil?
Gracias por tu ayuda !
Si está leyendo todo el nodo de chat , puede recorrer los distintos niveles de esta manera:
admin.database().ref('/chat').once('value').then((snapshot) => { snapshot.forEach((user1Snapshot) => { user1Snapshot.forEach((user2Snapshot) => { console.log(`Chat between ${user1Snapshot.key} and {$user2Snapshot.key}`); // TODO: perform a query on user2Snaphot.ref }) }) }) Sin embargo, esto lee todo el nodo de chats , incluidos los mensajes que no va a eliminar.
Si solo desea leer los datos que va a eliminar, debe conocer todos los pares de UID que existen en los chats .
La mejor manera de hacerlo es almacenar los pares de UID en algún lugar también, para que pueda acceder a ellos sin descargar todos los mensajes de chat. Entonces algo como:
"existing_chats": { "$uid1_$uid2": true, "$uid2_$uid3": true }Ahora puede leer los pares de UID de esta estructura, recorrerlos y luego realizar una consulta de corte para cada par.
Finalmente, también podría considerar mantener una sola lista plana de las rutas a todos los mensajes y la marca de tiempo de vencimiento como su valor:
"message_expirations": { "$uid1_$uid2_$messageid1": 127864586723459, "$uid1_$uid2_$messageid2": 127864586723469, ... } Con esto, puede hacer una sola consulta con orderByValue en los mensajes caducados y luego eliminarlos todos. Si bien conduce a la mayor parte de la duplicación de datos, es la representación más directa de su caso de uso en la estructura de datos, que a menudo encuentro más fácil de mantener.
Si elige este enfoque, no olvide eliminar también los nodos caducados de message_expirations (preferiblemente con una actualización de múltiples rutas), para que este nodo tampoco siga creciendo infinitamente.