¿Cómo puedo paginar en order descendente por valor de niño con base de fuego?

Digamos que tengo algunos datos de la siguiente manera:

{ "name": "post #1", "votes": 100 }, { "name": "post #2", "votes": 10000 }, { "name": "post #3", "votes": 750 } 

Y así.

Los datos en firebase no están orderados por votos obviamente, es order por key.

Me gustaría poder paginar esta información por el número de votos en order descendente.

Creo que tendría que hacer algo como:

 ref.orderByChild('votes') .startAt(someValue) .limitToFirst(someOtherValue) .once('value', function(snapshot) { resolve(snapshot); }); 

O tal vez, necesitaría usar limitToLast y endAt ?

La pagination por key es bastante fácil, pero esta me está golpeando.

Actualización (2017-10-16): Firebase anunció recientemente Firestre , su almacén de datos NoSQL totalmente gestionado, que debería facilitar la realización de consultas más complejas. Todavía puede haber algunos casos de uso donde uno podría usar la database en time real que siempre han proporcionado. Si eres una de esas personas, esta pregunta debería aplicarse.

Publiqué esta pregunta después de un largo día de encoding y mi cerebro estaba lleno de papilla.

Exploté esta mañana y, como suele ser el caso, pude encontrar la solución bastante rápido.

Solución:

Para paginar los datos, necesitamos la capacidad de extraer arbitrariamente los datos clasificados de la mitad de una list. Puede hacerlo utilizando las siguientes funciones proporcionadas por la API de firebase:

startAt

endAt

limitToFirst

limitToLast

Más información se puede encontrar aquí .

En mi caso, dado que necesito mis datos en order descendente, endAt y limitToLast .

Suponiendo que me gustaría que cada una de mis páginas tenga cinco elementos. Escribiría mi primera consulta así:

 ref.orderByChild('votes') .limitToLast(5) .once('value', function(snapshot) { console.log('Snap: ', snapshot.val()); }); 

Esto obtiene los 5 artículos con el mayor número de votos.

Para get la página siguiente, necesitaremos almacenar dos datos a partir de los resultados de nuestra última consulta. Necesitamos almacenar el número de votos y la key para el artículo que tuvo el menor número de votos. Es decir, el último elemento en nuestra list.

Al usar esos datos, nuestra próxima consulta y todas las consultas posteriores se verán de la siguiente manera:

 ref.orderByChild('votes') .endAt(previousVoteCount, previousKey) .limitToLast(5) .once('value', function(snapshot) { console.log('Snap: ', snapshot.val()); }); 

Notarás en esta consulta que agregué endAt . Esto obtiene los siguientes 5 elementos con la mayor cantidad de votos a partir del último de la list anterior. Debemos include la key del último elemento de la list anterior para que, si hay varios elementos con el mismo número de votos, devuelva una list que comience con el elemento correcto, y no la primera que encuentre con ese número. de votos, que podría estar en algún lugar en el medio de la list que obtuvo de la consulta inicial.

¡Eso es!