Mostra i post in ordine decrescente

Sto provando a testare Firebase per consentire agli utenti di pubblicare commenti usando push . Voglio visualizzare i dati che recupero con quanto segue;

 fbl.child('sell').limit(20).on("value", function(fbdata) { // handle data display here } 

Il problema è che i dati vengono restituiti in ordine dal più vecchio al più nuovo – lo voglio in ordine inverso. Firebase può farlo?

Poiché questa risposta è stata scritta, Firebase ha aggiunto una funzione che consente l’ordine da parte di qualsiasi bambino o valore. Quindi ora ci sono quattro modi per ordinare i dati: per chiave, per valore, per priorità o per valore di qualsiasi bambino con nome. Vedi questo post sul blog che introduce le nuove funzionalità di ordinamento .

Gli approcci di base rimangono gli stessi però:

1. Aggiungi una proprietà child con il timestamp invertito e quindi ordina quello.

2. Leggere i bambini in ordine crescente e quindi invertirli sul client.

Firebase supporta il recupero dei nodes figlio di una raccolta in due modi:

  • per nome
  • per priorità

Quello che stai ricevendo ora è per nome, che sembra essere cronologico. Non è una coincidenza: quando si push un object in una raccolta, il nome viene generato per garantire che i bambini siano ordinati in questo modo. Per citare la documentazione di Firebase per push :

Il nome univoco generato da push () è preceduto da un timestamp generato dal client in modo che l’elenco risultante sia ordinato cronologicamente.

La guida di Firebase sui dati ordinati ha questo da dire sull’argomento:

Come vengono ordinati i dati

Per impostazione predefinita, i bambini in un nodo Firebase vengono ordinati lessicograficamente per nome. L’uso di push() può generare nomi di bambini che ordinano naturalmente cronologicamente, ma molte applicazioni richiedono che i loro dati siano ordinati in altri modi. Firebase consente agli sviluppatori di specificare l’ordine degli articoli in un elenco specificando una priorità personalizzata per ciascun elemento.

Il modo più semplice per ottenere il comportamento desiderato è anche specificare una priorità sempre decrescente quando aggiungi l’elemento:

 var ref = new Firebase('https://your.firebaseio.com/sell'); var item = ref.push(); item.setWithPriority(yourObject, 0 - Date.now()); 

Aggiornare

Dovrai anche recuperare i bambini in modo diverso:

 fbl.child('sell').startAt().limit(20).on('child_added', function(fbdata) { console.log(fbdata.exportVal()); }) 

Nel mio test usando on('child_added' assicura che gli ultimi child aggiunti vengano restituiti in ordine cronologico inverso, usando on('value' d’altra parte, li restituisce nell’ordine del loro nome.

Assicurati di leggere la sezione “Leggere i dati ordinati” , che spiega l’uso degli eventi child_* per recuperare i bambini (ordinati).

Un cestino per dimostrarlo: http://jsbin.com/nonawe/3/watch?js,console

Dal momento che firebase 2.0.x puoi usare limitLast() per ottenere ciò:

 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 } 

Ecco un link all’annuncio: Ulteriori funzionalità di interrogazione in Firebase

Per aumentare la risposta di Frank, è anche ansible prendere i record più recenti – anche se non ti sei preso la briga di ordinarli usando le priorità – semplicemente usando endAt().limit(x) come questa 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... } 

Si noti che questo è abbastanza performante anche fino a forse un migliaio di record (supponendo che i payload siano piccoli). Per usi più robusti, la risposta di Frank è autorevole e molto più scalabile.

Questa forza bruta può anche essere ottimizzata per lavorare con dati più grandi o più record facendo cose come il monitoraggio di child_added / child_removed / child_moved al posto del value , e usando un debounce per applicare gli aggiornamenti DOM in blocco invece che individualmente.

Gli aggiornamenti DOM, naturalmente, sono un puzzone a prescindere dall’approccio, una volta entrati nelle centinaia di elementi, quindi l’approccio debounce (o una soluzione React.js, che è essenzialmente un ubriacone) è un ottimo strumento da avere.

Ho una variabile di data (lunga) e volevo mantenere gli elementi più recenti in cima alla lista. Quindi quello che ho fatto è stato:

  • Aggiungi un nuovo campo lungo ‘dateInverse’
  • Aggiungi un nuovo metodo chiamato ‘getDateInverse’, che restituisce solo: Long.MAX_VALUE – date;
  • Crea la mia domanda con: .orderByChild (“dateInverse”)
  • Presto! : p

Stai cercando limitTolast (Int x). Questo ti darà gli ultimi “x” elementi superiori del tuo database (sono in ordine crescente) ma sono gli elementi “x” più alti

se sei entrato nel tuo database {10,300,150,240,2,24,220}

questo metodo:

 myFirebaseRef.orderByChild("highScore").limitToLast(4) 

ti riacquisterà: {150,220,240,300}

Non c’è davvero alcun modo, ma sembra che abbiamo il recyclerview che possiamo avere questo

  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); 

Firebase: come visualizzare una sequenza di elementi in ordine inverso con un limite per ogni richiesta e un indicatore per un pulsante “carica altro”.

  • Questo otterrà gli ultimi 10 elementi della lista

FBRef.child (“childName”) .limitToLast (loadMoreLimit) // loadMoreLimit = 10 ad esempio

  • Questo otterrà gli ultimi 10 articoli. Prendi l’id dell’ultimo record nell’elenco e salva per il carico più funzionalità. Successivamente, converti la raccolta di oggetti in e una matrice e fai un elenco.reverse ().

  • CARICA DI PIÙ Funzionalità: la prossima chiamata farà due cose, otterrà la successiva sequenza di voci di elenco basata sull’ID di riferimento dalla prima richiesta e ti darà un indicatore se è necessario visualizzare il pulsante “carica più”.

this.FBRef .child (“childName”) .endAt (null, lastThreadId) // Ottieni questo dal punto precedente .limitToLast (loadMoreLimit + 2)

  • Sarà necessario rimuovere il primo e l’ultimo elemento di questa raccolta di oggetti. Il primo elemento è il riferimento per ottenere questa lista. L’ultimo elemento è un indicatore per il pulsante mostra più.

  • Ho un sacco di altre logiche che manterranno tutto pulito. Dovrai aggiungere questo codice solo per il caricamento di più funzionalità.

      list = snapObjectAsArray; // The list is an array from snapObject lastItemId = key; // get the first key of the list if (list.length < loadMoreLimit+1) { lastItemId = false; } if (list.length > loadMoreLimit+1) { list.pop(); } if (list.length > loadMoreLimit) { list.shift(); } // Return the list.reverse() and lastItemId // If lastItemId is an ID, it will be used for the next reference and a flag to show the "load more" button. } 

Sto usando ReactFire per una facile integrazione con Firebase.

Fondamentalmente, mi aiuta a memorizzare i dati nello stato del componente, come una array . Quindi, tutto quello che devo usare è la funzione reverse() ( leggi di più )

Ecco come raggiungo questo:

 import React, { Component, PropTypes } from 'react'; import ReactMixin from 'react-mixin'; import ReactFireMixin from 'reactfire'; import Firebase from '../../../utils/firebaseUtils'; // Firebase.initializeApp(config); @ReactMixin.decorate(ReactFireMixin) export default class Add extends Component { constructor(args) { super(args); this.state = { articles: [] }; } componentWillMount() { let ref = Firebase.database().ref('articles').orderByChild('insertDate').limitToLast(10); this.bindAsArray(ref, 'articles'); // bind retrieved data to this.state.articles } render() { return ( 
{ this.state.articles.reverse().map(function(article) { return
{article.title}
}) }
); } }

In Android c’è un modo per invertire effettivamente i dati in un Arraylist di oggetti attraverso l’adattatore. Nel mio caso non ho potuto usare il LayoutManager per invertire i risultati in ordine decrescente poiché stavo usando un Recyclerview orizzontale per visualizzare i dati. L’impostazione dei seguenti parametri per il recyclerview ha rovinato la mia esperienza di interfaccia utente:

 llManager.setReverseLayout(true); llManager.setStackFromEnd(true); 

L’unico modo di lavorare che ho trovato in giro era attraverso il metodo BindViewHolder dell’adattatore RecyclerView:

 @Override public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { final SuperPost superPost = superList.get(getItemCount() - position - 1); } 

Spero che questa risposta possa aiutare tutti gli sviluppatori che stanno lottando con questo problema in Firebase.

C’è un modo migliore. È necessario effettuare l’ordine in base al timestamp del server negativo. Come ottenere il timestamp del server negativo anche offline? C’è un campo nascosto che aiuta. Snippet correlato dalla documentazione:

 var offsetRef = new Firebase("https://.firebaseio.com/.info/serverTimeOffset"); offsetRef.on("value", function(snap) { var offset = snap.val(); var estimatedServerTimeMs = new Date().getTime() + offset; }); 

Per aggiungere alla risposta di Dave Vávra, io uso un timestamp negativo come il mio sort_key così

Ambientazione

 const timestamp = new Date().getTime(); const data = { name: 'John Doe', city: 'New York', sort_key: timestamp * -1 // Gets the negative value of the timestamp } 

ottenere

 const ref = firebase.database().ref('business-images').child(id); const query = ref.orderByChild('sort_key'); return $firebaseArray(query); // AngularFire function 

Questo recupera tutti gli oggetti dal più recente al più vecchio. Puoi anche $indexOn the sortKey per farlo funzionare ancora più velocemente

Ho avuto anche questo problema, ho trovato una soluzione molto semplice a questo che non comportava la manipolazione dei dati in alcun modo. Se stai strappando il risultato al DOM, in una lista di qualche tipo. Puoi usare flexbox e configurare una class per invertire gli elementi nel loro contenitore.

 .reverse { display: flex; flex-direction: column-reverse; } 

L’ho fatto anticipatamente.

 query.orderByChild('sell').limitToLast(4).on("value", function(snapshot){ snapshot.forEach(function (childSnapshot) { // PREPEND }); }); 

Qualcuno ha sottolineato che ci sono 2 modi per farlo:

  1. Manipola i dati lato client
  2. Fai una query che ordinerà i dati

Il modo più semplice che ho trovato per farlo è quello di utilizzare l’opzione 1, ma attraverso una LinkedList . Applico solo ciascuno degli oggetti in cima alla pila. È abbastanza flessibile da consentire comunque l’utilizzo dell’elenco in ListView o RecyclerView . In questo modo, anche se arrivano in ordine dal più vecchio al più recente, puoi comunque visualizzare o recuperare, dal più recente al più vecchio.

È ansible aggiungere una colonna denominata orderColumn in cui si salva l’ora come

Long refrenceTime = "large future time"; Long currentTime = "currentTime"; Long order = refrenceTime - currentTime;

ora salva l’ordine lungo nella colonna denominata orderColumn e quando recuperi i dati come orderBy (orderColumn) otterrai ciò di cui hai bisogno.

basta usare reverse() sull’array, supponiamo che stiate memorizzando i valori su un array items[] quindi this.items.reverse() un this.items.reverse()

  ref.subscribe(snapshots => { this.loading.dismiss(); this.items = []; snapshots.forEach(snapshot => { this.items.push(snapshot); }); **this.items.reverse();** },