En Firebase, ¿hay alguna forma de obtener el número de hijos de un nodo sin cargar todos los datos del nodo?

Puedes hacer que el niño cuente a través de

firebase_node.once('value', function(snapshot) { alert('Count: ' + snapshot.numChildren()); }); 

Pero creo que esto obtiene el subárbol completo de ese nodo del servidor. Para listas enormes, eso parece RAM y latencia intensiva. ¿Hay alguna manera de obtener el recuento (y / o una lista de nombres de niños) sin obtener todo el asunto?

El fragmento de código que proporcionó sí carga todo el conjunto de datos y luego lo cuenta en el lado del cliente, que puede ser muy lento para grandes cantidades de datos.

Firebase no cuenta actualmente con una forma de contar niños sin cargar datos, pero planeamos agregarlo.

Por ahora, una solución sería mantener un contador del número de hijos y actualizarlo cada vez que agregue un nuevo hijo. Puede usar una transacción para contar elementos, como en este código que rastrea updesdes:

 var upvotesRef = new Firebase('https://docs-examples.firebaseio.com/android/saving-data/fireblog/posts/-JRHTHaIs-jNPLXOQivY/upvotes'); upvotesRef.transaction(function (current_value) { return (current_value || 0) + 1; }); 

Para obtener más información, consulte https://www.firebase.com/docs/transactions.html

ACTUALIZACIÓN: Firebase lanzó recientemente Cloud Functions. Con Cloud Functions, no necesita crear su propio servidor. Simplemente puede escribir funciones de JavaScript y subirlas a Firebase. Firebase será responsable de activar funciones cada vez que ocurra un evento.

Si desea contar votaciones ascendentes, por ejemplo, debe crear una estructura similar a esta:

 { "posts" : { "-JRHTHaIs-jNPLXOQivY" : { "upvotes_count":5, "upvotes" : { "userX" : true, "userY" : true, "userZ" : true, ... } } } } 

Y luego escriba una función de JavaScript para boost la cuenta de upvotes_count cuando haya una nueva escritura en el nodo de upvotes a upvotes .

 const functions = require('firebase-functions'); const admin = require('firebase-admin'); admin.initializeApp(functions.config().firebase); exports.countlikes = functions.database.ref('/posts/$postid/upvotes').onWrite(event => { return event.data.ref.parent.child('upvotes_count').set(event.data.numChildren()); }); 

Puede leer la documentación para saber cómo comenzar con las funciones de la nube .

Además, hay otro ejemplo de conteo de publicaciones aquí: https://github.com/firebase/functions-samples/blob/master/child-count/functions/index.js

Esto es un poco tarde en el juego ya que muchos otros ya han respondido bien, pero les contaré cómo podría implementarlo.

Esto depende del hecho de que la API REST de Firebase ofrece un parámetro shallow=true .

Supongamos que tiene un objeto de post y cada uno puede tener una serie de comments :

 { "posts": { "$postKey": { "comments": { ... } } } } 

Obviamente no quiere buscar todos los comentarios, solo la cantidad de comentarios.

Suponiendo que tiene la clave para una publicación, puede enviar una solicitud GET a https://yourapp.firebaseio.com/posts/[the post key]/comments?shallow=true .

Esto devolverá un objeto de pares clave-valor, donde cada clave es la clave de un comentario y su valor es true :

 { "comment1key": true, "comment2key": true, ..., "comment9999key": true } 

El tamaño de esta respuesta es mucho menor que solicitar los datos equivalentes, y ahora puede calcular el número de claves en la respuesta para encontrar su valor (por ejemplo, commentCount = Object.keys(result).length ).

Es posible que esto no resuelva completamente su problema, ya que aún está calculando la cantidad de claves devueltas, y no necesariamente puede suscribirse al valor a medida que cambia, pero reduce en gran medida el tamaño de los datos devueltos sin requerir ningún cambio en su esquema.

Guarde el recuento sobre la marcha y utilice la validación para aplicarlo. Lo pirateé todo para mantener un conteo de votos únicos y conteos que siguen apareciendo. ¡Pero esta vez he probado mi sugerencia! (¡a pesar de los errores de cortar / pegar!).

El ‘truco’ aquí es usar la prioridad de nodo como el conteo de votos …

La información es:

vote / $ issueBeingVotedOn / user / $ uniqueIdOfVoter = thisVotesCount, priority = thisVotesCount vote / $ issueBeingVotedOn / count = ‘user /’ + $ idOfLastVoter, priority = CountofLastVote

 ,"vote": { ".read" : true ,".write" : true ,"$issue" : { "user" : { "$user" : { ".validate" : "!data.exists() && newData.val()==data.parent().parent().child('count').getPriority()+1 && newData.val()==newData.GetPriority()" 

el usuario solo puede votar una vez y el recuento debe ser uno más alto que el conteo actual y el valor de los datos debe ser igual a la prioridad.

  } } ,"count" : { ".validate" : "data.parent().child(newData.val()).val()==newData.getPriority() && newData.getPriority()==data.getPriority()+1 " } 

contar (último votante realmente) – el voto debe existir y su recuento es igual a nueva cuenta, && nueva cuenta (prioridad) solo puede subir en uno.

  } } 

Script de prueba para agregar 10 votos por diferentes usuarios (para este ejemplo, el nombre falso del identificador debe ser el usuario auth.uid en producción). Cuente hacia abajo por (i–) 10 para ver que la validación falla.

   

El "riesgo" aquí es que se emite un voto, pero el recuento no se actualiza (fallas de anotaciones o guiones). Esta es la razón por la cual los votos tienen una 'prioridad' única: el guión realmente debe comenzar asegurándose de que no hay voto con prioridad más alta que el conteo actual, si es que debe completar esa transacción antes de hacer lo propio, haga que sus clientes limpien para ti 🙂

El recuento debe inicializarse con una prioridad antes de comenzar. Forge no te permite hacer esto, por lo que se necesita un guión de código auxiliar (¡antes de que la validación esté activada!).

escribir una función de nube y actualizar el recuento de nodos.

 // below function to get the given node count. const functions = require('firebase-functions'); const admin = require('firebase-admin'); admin.initializeApp(functions.config().firebase); exports.userscount = functions.database.ref('/users/') .onWrite(event => { console.log('users number : ', event.data.numChildren()); return event.data.ref.parent.child('count/users').set(event.data.numChildren()); }); 

Consulte: https://firebase.google.com/docs/functions/database-events

root– | | -users (este nodo contiene la lista de todos los usuarios) |
| -count | -userscount: (este nodo se agregó dinámicamente mediante la función de nube con el recuento de usuarios)

Aprecio que esto es 2 años después de la pregunta abierta, pero como su primer resultado en google pensé que lo actualizaría ya que actualmente estoy buscando una manera de obtener el conteo de objetos de niños. Esto se puede hacer con

Se proporciona el método DataSnapshot.numChildren (), se pueden encontrar más detalles aquí – Sitio web de Firebase