Mostrar publicaciones en orden descendente
Estoy intentando probar Firebase para permitir a los usuarios publicar comentarios usando push
. Quiero mostrar los datos que recupero con lo siguiente;
fbl.child('sell').limit(20).on("value", function(fbdata) {
// handle data display here
}
El problema es que los datos se devuelven en orden del más antiguo al más nuevo; los quiero en orden inverso. ¿Puede Firebase hacer esto?
Desde que se escribió esta respuesta, Firebase ha agregado una función que permite realizar pedidos por cualquier elemento secundario o por valor. Así que ahora hay cuatro formas de ordenar los datos: por clave, por valor, por prioridad o por el valor de cualquier hijo nombrado. Consulte esta publicación de blog que presenta las nuevas capacidades de pedidos .
Sin embargo, los enfoques básicos siguen siendo los mismos:
1. Agregue una propiedad secundaria con la marca de tiempo invertida y luego ordénela.
2. Lea los niños en orden ascendente y luego inviértalos en el cliente.
Firebase admite la recuperación de nodos secundarios de una colección de dos maneras:
- por nombre
- por prioridad
Lo que obtienes ahora es por nombre, que resulta ser cronológico. Por cierto, no es una coincidencia: cuando incluyes push
un elemento en una colección, el nombre se genera para garantizar que los elementos secundarios estén ordenados de esta manera. Para citar la documentación de Firebase parapush
:
El nombre único generado por push() tiene como prefijo una marca de tiempo generada por el cliente para que la lista resultante se ordene cronológicamente.
La guía de Firebase sobre datos ordenados tiene esto que decir sobre el tema:
Cómo se ordenan los datos
De forma predeterminada, los elementos secundarios de un nodo de Firebase se ordenan lexicográficamente por nombre. El uso
push()
puede generar nombres de niños que se ordenan cronológicamente de forma natural, pero muchas aplicaciones requieren que sus datos se ordenen de otras maneras. Firebase permite a los desarrolladores especificar el orden de los elementos en una lista especificando una prioridad personalizada para cada elemento.
La forma más sencilla de obtener el comportamiento que desea es especificar también una prioridad siempre decreciente cuando agrega el elemento:
var ref = new Firebase('https://your.firebaseio.com/sell');
var item = ref.push();
item.setWithPriority(yourObject, 0 - Date.now());
Actualizar
También tendrás que recuperar a los niños de manera diferente:
fbl.child('sell').startAt().limitToLast(20).on('child_added', function(fbdata) {
console.log(fbdata.exportVal());
})
En mi prueba, el uso on('child_added'
garantiza que los últimos niños agregados se devuelvan en orden cronológico inverso. Usando on('value'
por otro lado, los devuelve en el orden de su nombre.
Asegúrese de leer la sección "Lectura de datos ordenados" , que explica el uso de child_*
eventos para recuperar niños (ordenados).
Un contenedor para demostrar esto: http://jsbin.com/nonawe/3/watch?js,console
Desde firebase 2.0.x puedes usar limitLast()
para lograr eso:
fbl.child('sell').orderByValue().limitLast(20).on("value", function(fbdataSnapshot) {
// fbdataSnapshot is returned in the ascending order
// you will still need to order these 20 items in
// in a descending order
}
Aquí hay un enlace al anuncio: Más capacidades de consulta en Firebase
Para mejorar la respuesta de Frank, también es posible obtener los registros más recientes, incluso si no te has molestado en ordenarlos usando prioridades, simplemente usando endAt().limit(x)
así demo:
var fb = new Firebase(URL);
// listen for all changes and update
fb.endAt().limit(100).on('value', update);
// print the output of our array
function update(snap) {
var list = [];
snap.forEach(function(ss) {
var data = ss.val();
data['.priority'] = ss.getPriority();
data['.name'] = ss.name();
list.unshift(data);
});
// print/process the results...
}
Tenga en cuenta que esto es bastante eficaz incluso hasta quizás mil registros (suponiendo que las cargas útiles sean pequeñas). Para usos más sólidos, la respuesta de Frank tiene autoridad y es mucho más escalable.
Esta fuerza bruta también se puede optimizar para trabajar con datos más grandes o más registros haciendo cosas como monitorear child_added
// eventos en lugar de child_removed
y usar un rebote para aplicar actualizaciones DOM de forma masiva en lugar de individualmente.child_moved
value
Las actualizaciones de DOM, naturalmente, son un asco independientemente del enfoque, una vez que ingresas a los cientos de elementos, por lo que el enfoque antirrebote (o una solución React.js, que es esencialmente un súper antirrebote) es una gran herramienta.
Realmente no hay manera, pero parece que tenemos la vista del reciclador y podemos tener esto.
query=mCommentsReference.orderByChild("date_added");
query.keepSynced(true);
// Initialize Views
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
mManager = new LinearLayoutManager(getContext());
// mManager.setReverseLayout(false);
mManager.setReverseLayout(true);
mManager.setStackFromEnd(true);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(mManager);