Mostrar publicaciones en orden descendente

Resuelto user2912591 asked hace 55 años • 0 respuestas

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?

user2912591 avatar Jan 01 '70 08:01 user2912591
Aceptado

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 pushun 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

Frank van Puffelen avatar Sep 01 '2014 21:09 Frank van Puffelen

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

Maksymilian Majer avatar Apr 16 '2015 14:04 Maksymilian Majer

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_removedy usar un rebote para aplicar actualizaciones DOM de forma masiva en lugar de individualmente.child_movedvalue

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.

Kato avatar Sep 03 '2014 14:09 Kato

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);
Goodlife avatar Oct 27 '2016 08:10 Goodlife