risposta Aggiornato
@Tyler rispondere stackoverflow.com/a/38024909/681290 è una più aggiornata e la risposta più conveniente per questa domanda
TL; DR
Non c'è soluzione se quello che stanno cercando di fare è:
ref.orderBy(field, 'DESC').offset(n).limit(x)
Inoltre, nel github di Firebase sono presenti strumenti non supportati that do pagination, sebbene solo nell'ordine ascendente solo.
Altrimenti, qui ci sono le soluzioni più vicine possibili, che ho trovato io stesso, o sul web finora. Ho deliberatamente interpretato la domanda come generica, non solo sui campi temporali come richiesto dall'OP.
Utilizzare priorità
L'obiettivo è quello di utilizzare setWithPriority()
e setPriority()
sui bambini per essere in grado di ottenere i dati ordinati in seguito con orderByPriority()
.
Issues:
- non vedo il vantaggio rispetto utilizzando un indicizzato
priority
campo, invece? (In realtà, la priorità viene memorizzato come un campo sottostante chiamato .priority
, che si può vedere quando l'esportazione dei dati JSON)
- difficile da mantenere per molti casi d'uso, per determinare il valore di priorità per impostare
campi bambino ridondante con dati negativi
per esempio, possiamo usare un timestamp timeRev
campo indicizzato negativo in aggiunta a time
essere in grado di ottenere gli elementi più recenti.
ref.orderByChild('timeRev')
.limitToFirst(100);
Issues:
- aggiunge ulteriore complessità al app: campi aggiuntivi devono essere mantenuti
- può rompere atomicità del campo (ad esempio un campo
score
può essere aggiornato in una sola volta, Non sono sicuro se sia possibile con due campi, uno positivo e uno negativo)
- Penso che questa soluzione alternativa sia stata utilizzata quando c'era solo
limit()
nell'API Firebase, ma è un po 'obsoleto ora che possiamo usare limitToFist()
, limitToLast()
, e la gamma di query (vedi sotto)
Utilizzando limitToLast() e endAt()
gamma query
Questo Evitiamo campo negativo e ridondante:
ref.orderBy('time')
.limitToLast(100)
Questo dovrebbe essere piuttosto efficace con i campi di timestamp, perché di solito questo è un campo unico.
L'array risultante di elementi deve semplicemente essere invertito prima dell'uso. (Basta ricordare Array.prototype.reverse()
è mutevole, in modo che cambierà la vostra array)
Issues:
- la documentazione API dicono che solo il valore della chiave ordinata può essere impostato come un
startAt
o endAt
confine. Se molti articoli condividono lo stesso valore, il set di dati non può essere suddiviso in offset di lunghezza fissa.
Esempio con i seguenti elementi in possesso di un valore di score
:
{
items: {
a: {score: 0},
b: {score: 0},
c: {score: 1},
d: {score: 1},
e: {score: 2},
f: {score: 5}
}
}
prima query pagina per ottenere i migliori elementi di punteggio:
ref.child('items').orderByChild('score')
.limitToLast(3)
risultati:
{
d: {score: 1},
e: {score: 2},
f: {score: 5}
}
Nota il primo elemento del sottoinsieme h come una partitura 1
, quindi cerchiamo di ottenere la pagina precedente selezionando tutte le voci con punteggio di 1
o meno:
ref.child('items').orderByChild('score')
.endAt(1)
.limitToLast(3)
Con tale query, otteniamo b,c,d
articoli, invece di a,b,c
elementi, che si prevede come da i documenti API, dato il numero endAt(1)
, sono comprensivi, quindi cercherà di ottenere tutti i punteggi di 1 e non ha modo di ordinare quelli che sono già stati restituiti in precedenza.
Soluzione
Questo può essere attenuato non aspettati ogni sottoinsieme di tenere la stessa quantità di record e scartando quelle già caricato.
Ma, se il primo milione di utenti della mia app hanno un punteggio 0
, questo sottoinsieme non può essere impaginato, perché il endAt
offset è inutile, in quanto si basa sul valore invece del numero di record.
non vedo alcuna soluzione per questo caso d'uso, immagino Firebase non è destinato a questo :-)
Edit: Alla fine, io sto usando Algolia per tutti gli usi di ricerca-correlato. È un'API davvero carina, e spero che Google finisca per acquisire Algolia per integrare sia Firebase & Algolia, in quanto la loro complementarità è vicina al 100%! Disclaimer: nessuna proprietà posseduta !! :-)
"Sembra che l'unico modo per visualizzare i record Firebase in ordine inverso sia quello di recuperarli tutti e poi scorrere su di essi al contrario." Potresti voler rileggere la documenazione, in particolare su 'limite'. https://www.firebase.com/docs/web/guide/retrieving-data.html#section-queries –
Grazie Frank, ero a conoscenza di quei documenti. La priorità può essere utilizzata per ordinare in diversi ordini, ma ho difficoltà a pensare a un modo efficace di impostare la priorità di un elemento in un modo che potrebbe essere ordinato in ordine cronologico inverso. Puoi? – cayblood
Non solo per priorità, puoi ordinarlo oggigiorno da qualsiasi bambino usando 'orderByChild'. Leggi questo post del blog per aggiornarti: https://www.firebase.com/blog/2014-11-04-firebase-realtime-queries.html. Qualcosa come "orderByChild" seguito da "limitToLast" e quindi "Array.reverse" dovrebbe fare ciò che è necessario per te. –