J'essaie de tester Firebase pour permettre aux utilisateurs de poster des commentaires en utilisant Push
. Je veux afficher les données que je récupère avec ce qui suit:
fbl.child('sell').limit(20).on("value", function(fbdata) {
// handle data display here
}
Le problème est que les données sont renvoyées dans l’ordre le plus ancien au plus récent; Est-ce que Firebase peut faire ça?
Depuis que cette réponse a été écrite, Firebase a ajouté une fonctionnalité permettant de classer par enfant ou par valeur. Donc, il existe maintenant quatre façons de commander des données: par clé, par valeur, par priorité ou par la valeur de tout enfant nommé. Voir cet article de blog qui présente les nouvelles fonctionnalités de commande .
Les approches de base restent les mêmes cependant:
1. Ajoutez une propriété enfant avec l'horodatage inversé, puis commandez-la.
2. Lisez les enfants dans l'ordre croissant, puis inversez-les sur le client.
Firebase prend en charge la récupération des nœuds enfants d'une collection de deux manières:
Ce que vous obtenez maintenant est un nom, qui se trouve être chronologique. Ce n'est pas un hasard si: lorsque vous Push
un élément dans une collection, le nom est généré pour garantir que les enfants sont classés de cette manière. Pour citer la documentation Firebase pour Push
:
Le nom unique généré par Push () est préfixé par un horodatage généré par le client afin que la liste résultante soit triée de manière chronologique.
Le Guide Firebase sur les données ordonnées a ceci à dire sur le sujet:
Comment les données sont commandées
Par défaut, les enfants d'un nœud Firebase sont triés lexicographiquement par nom. L'utilisation de
Push()
peut générer des noms d'enfants qui trieront naturellement par ordre chronologique, mais de nombreuses applications exigent que leurs données soient triées d'une autre manière. Firebase permet aux développeurs de spécifier l'ordre des éléments dans une liste en spécifiant une priorité personnalisée pour chaque élément.
Le moyen le plus simple d'obtenir le comportement souhaité consiste à spécifier également une priorité toujours décroissante lorsque vous ajoutez l'élément:
var ref = new Firebase('https://your.firebaseio.com/sell');
var item = ref.Push();
item.setWithPriority(yourObject, 0 - Date.now());
Vous devrez également récupérer les enfants différemment:
fbl.child('sell').startAt().limit(20).on('child_added', function(fbdata) {
console.log(fbdata.exportVal());
})
Dans mon test, utiliser on('child_added'
garantit que les derniers enfants ajoutés sont renvoyés dans l'ordre chronologique inverse. Par contre, en utilisant on('value'
, les renvoie dans l'ordre de leur nom.
Assurez-vous de lire la section "Lecture des données ordonnées" , qui explique l'utilisation des événements child_*
pour récupérer des enfants (ordonnés).
Un bin pour le démontrer: http://jsbin.com/nonawe/3/watch?js,console
Depuis firebase 2.0.x, vous pouvez utiliser limitLast()
pour y parvenir:
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
}
Voici un lien vers l'annonce: Davantage de fonctionnalités d'interrogation dans Firebase
Il n'y a vraiment aucun moyen mais semble que nous avons le recyclage nous pouvons avoir cette
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);
J'ai une date variable (long) et je voulais garder les articles les plus récents en haut de la liste. Alors ce que j'ai fait était:
Vous recherchez limitTolast (Int x). Cela vous donnera les derniers "x" éléments supérieurs de votre base de données (ils sont classés par ordre croissant), mais il s'agit des "x" éléments supérieurs
si vous avez dans votre base de données {10 300,150,240,2,24,220}
cette méthode:
myFirebaseRef.orderByChild("highScore").limitToLast(4)
vous recopierons: {150,220,240,300}
Dans Android, il existe un moyen d'inverser réellement les données dans un tableau d'objets à l'aide de l'adaptateur. Dans mon cas, je ne pouvais pas utiliser LayoutManager pour inverser les résultats dans l'ordre décroissant, car j'utilisais une vue de recyclage horizontale pour afficher les données. La définition des paramètres suivants dans Recyclerview a gâché mon expérience d'interface utilisateur:
llManager.setReverseLayout(true);
llManager.setStackFromEnd(true);
Le seul moyen efficace que j'ai trouvé à ce propos était d'utiliser la méthode BindViewHolder de l'adaptateur RecyclerView:
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
final SuperPost superPost = superList.get(getItemCount() - position - 1);
}
J'espère que cette réponse aidera tous les développeurs qui sont aux prises avec ce problème dans Firebase.
Firebase: Comment afficher un fil d’éléments dans l’ordre inverse avec une limite pour chaque demande et un indicateur pour un bouton "Charger plus".
FBRef.child ("ChildName") .limitToLast (loadMoreLimit) // loadMoreLimit = 10 par exemple
Cela va obtenir les 10 derniers articles. Saisissez l'id du dernier enregistrement de la liste et enregistrez pour le chargement plus de fonctionnalités. Ensuite, convertissez la collection d'objets en un tableau et effectuez une commande list.reverse ().
LOAD MORE Fonctionnalité: le prochain appel fera deux choses: il obtiendra la prochaine séquence d'éléments de liste en fonction de l'ID de référence de la première demande et vous indiquera si vous devez afficher le bouton "charger plus".
this.FBRef .child ("childName") .endAt (null, lastThreadId) // Extrait ceci de l'étape précédente .limitToLast (loadMoreLimit + 2)
Vous devrez supprimer le premier et le dernier élément de cette collection d'objets. Le premier élément est la référence pour obtenir cette liste. Le dernier élément est un indicateur pour le bouton Afficher plus.
J'ai un tas d'autres logiques qui vont tout garder propre. Vous devrez ajouter ce code uniquement pour charger plus de fonctionnalités.
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.
}
J'utilise ReactFire pour une intégration facile de Firebase.
Fondamentalement, cela m’aide à stocker les données dans l’état du composant, sous la forme array
. Ensuite, tout ce que je dois utiliser est la fonction reverse()
( en savoir plus )
Voici comment je réalise ceci:
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 (
<div>
{
this.state.articles.reverse().map(function(article) {
return <div>{article.title}</div>
})
}
</div>
);
}
}
Il y a un meilleur moyen. Vous devriez commander par horodatage négatif du serveur. Comment obtenir un horodatage négatif du serveur, même hors ligne? Il y a un champ caché qui aide. Extrait associé de la documentation:
var offsetRef = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com/.info/serverTimeOffset");
offsetRef.on("value", function(snap) {
var offset = snap.val();
var estimatedServerTimeMs = new Date().getTime() + offset;
});
Pour ajouter à la réponse de Dave Vávra, j’utilise un horodatage négatif comme étant mon sort_key
like so
Réglage
const timestamp = new Date().getTime();
const data = {
name: 'John Doe',
city: 'New York',
sort_key: timestamp * -1 // Gets the negative value of the timestamp
}
Obtenir
const ref = firebase.database().ref('business-images').child(id);
const query = ref.orderByChild('sort_key');
return $firebaseArray(query); // AngularFire function
Ceci récupère tous les objets du plus récent au plus ancien. Vous pouvez également $indexOn
la sortKey
pour le rendre encore plus rapide
J'ai eu ce problème aussi, j'ai trouvé une solution très simple à ce problème qui n'implique aucune manipulation des données. Si vous restituez le résultat dans le DOM, dans une liste quelconque. Vous pouvez utiliser flexbox et configurer une classe pour inverser les éléments de leur conteneur.
.reverse {
display: flex;
flex-direction: column-reverse;
}
array.reverse (); ou this.items = items.map (item => item) .reverse ();
Vous pouvez ajouter une colonne appelée orderColumn où vous gagnez du temps en tant que
Long refrenceTime = "large future time";
Long currentTime = "currentTime";
Long order = refrenceTime - currentTime;
save save Long order dans la colonne nommée orderColumn et lorsque vous récupérerez des données.
Je l'ai fait par avance.
query.orderByChild('sell').limitToLast(4).on("value", function(snapshot){
snapshot.forEach(function (childSnapshot) {
// PREPEND
});
});
utilisez simplement reverse()
sur le tableau, supposez que si vous stockez les valeurs dans un tableau items[]
, faites un this.items.reverse()
ref.subscribe(snapshots => {
this.loading.dismiss();
this.items = [];
snapshots.forEach(snapshot => {
this.items.Push(snapshot);
});
**this.items.reverse();**
},
Quelqu'un a souligné qu'il y avait 2 façons de faire cela:
Pour ce faire, le moyen le plus simple consiste à utiliser l'option 1, mais à l'aide d'une variable LinkedList
. Je viens d'ajouter chaque objet à l'avant de la pile. Il est suffisamment souple pour autoriser la liste à être utilisée dans ListView
ou RecyclerView
. De cette façon, même s’ils arrivent du plus ancien au plus récent, vous pouvez toujours afficher ou récupérer du plus récent au plus ancien.