recuperar query guardar from datos data consultas javascript firebase firebase-database nosql

javascript - guardar - query firebase android



Contador de Firebase, casos de actualizaciones de volumen (1)

Está buscando transacciones , ¿verdad?

Al trabajar con datos que podrían estar dañados por modificaciones simultáneas, como contadores incrementales, puede usar una operación de transacción. Puede darle a esta operación una función de actualización y una devolución de llamada de finalización opcional. La función de actualización toma el estado actual de los datos como un argumento y devuelve el nuevo estado deseado que desea escribir. Si otro cliente escribe en la ubicación antes de escribir con éxito su nuevo valor, su función de actualización se llama nuevamente con el nuevo valor actual, y la escritura se reintenta.

Ejemplo de documentos:

function toggleStar(postRef, uid) { postRef.transaction(function(post) { if (post) { if (post.stars && post.stars[uid]) { post.starCount--; post.stars[uid] = null; } else { post.starCount++; if (!post.stars) { post.stars = {}; } post.stars[uid] = true; } } return post; }); }

Como una adición, puede eliminar solo el contenido publicado por el usuario eliminado, por lo que los contadores se mantendrán con el mismo valor y en lugar de comentario / publicación habrá "Se eliminó la publicación".

Sabemos que Firebase no tiene una consulta de conteo, los métodos para tener un contador son dos, obtener todos los datos en el lado del cliente o almacenar un valor de conteo en la base de datos. Utilizo este segundo método porque el primero es válido solo cuando hay pocos datos.

El problema con este método es que puedo tener muchos escritores simultáneos, resolví este problema con mi método que, si no se almacenan datos, intenta volver a guardar los datos con un contador incrementado o decrementado.

OK, este método funcionó bien cuando quiero cambiar solo un contador, pero en diferentes casos quiero cambiar muchos contadores diferentes con una transacción y en este modo existe el riesgo de que después de diferentes intentos no se puedan guardar los datos, porque podemos tener muchos escritores simultáneos en muchos nodos diferentes. Un ejemplo de estructura de datos con actualizaciones atómicas es el siguiente:

Si guardo esto

"comment": { "counter": {}, "Data": { "$Comment":{} } } comment/counter = val + 1 comment/Data/comment1 = data

funciona si no puedo actualizar porque otro escritor está actualizando el contador justo cuando puedo volver a intentarlo con un nuevo valor de contador y generalmente después de la primera vez que concluyo la operación con éxito, pero, por ejemplo, si quiero eliminar un usuario y todo sus acciones, quiero almacenar este tipo de datos

"comment":{ "counter":{}, "Data": { "$Comment":{} } }, "$user": { "follower":{ "counter":{}, "data":{ "$Follower": {} } } } comment/counter = val - 1 comment/Data/comment2 = null user1/follower/counter = val - 1 user1/follower/data/user30 = null user2/follower/counter = val - 1 user2/follower/data/user30 = null user3/follower/counter = val - 1 user3/follower/data/user30 = null

Es visible que en el caso de una actualización masiva, debo actualizar una gran cantidad de contadores que pueden tener muchos escritores simultáneos y en este caso es muy fácil que sea imposible poder actualizar todos los contadores después de diferentes intentos.

otro caso es este

"photo":{ "$photo":{ "comment":{ "counter":{}, "Data": { "$Comment":{} } } } photo/10/comment/counter = val - 1 photo/10/comment/Data/comment1 = null photo/10/comment/counter = val - 1 photo/10/comment/Data/comment2 = null photo/10/comment/counter = val - 1 photo/10/comment/Data/comment3 = null

En este caso, es imposible actualizar el contador porque trato de eliminar diferentes comentarios con el mismo contador que puede ser igual solo para el valor + 1 o para el valor 1. Si quiero eliminar todos los datos del usuario, es posible que escriba algunos comentarios en la misma foto pero no puedo eliminar todos estos comentarios en una transacción porque el contador se puede actualizar solo con una sola transacción.

Veo muchas de esas complicaciones solo porque no existe una consulta de conteo que exista en cualquier tipo de base de datos (sql o nosql). No entiendo porque. Esto implica una gran cantidad de problemas de otro modo solucionables sin perder tiempo

a continuación está mi función javascript para actualizar un contador. Es una función recursiva que se recuerda a sí misma si falla la actualización debido a otros escritores concurrentes

this.singleUpdate = function (paths, increment, countPath, retryCounter, callback) { firebase.database().ref(countPath).once(''value'', function (counter) { var value = counter.val() ? counter.val().value : 0; var countValue = increment ? value + 1 : value - 1; paths[countPath] = { value: null }; if (!increment && countValue == 0) { paths[countPath] = null; } else { paths[countPath].value = countValue; } firebase.database().ref().update(paths, function (error) { if (error) { retryCounter++; if (retryCounter < 3) { singleUpdate(paths, increment, countPath, retryCounter, callback); } else { callback(false, error); } } else { return callback(true, countValue); } }); }); }