Pour une application iOS sur laquelle je travaille, je dois récupérer les messages dans l'ordre décroissant, c'est-à-dire que le dernier message vient en premier, suivi du deuxième message le plus récent, etc.

En examinant d'autres réponses et recherches SO, il semble que la meilleure approche pour ma situation consiste à créer un horodatage négatif, puis à le conserver dans la base de données en tant que propriété supplémentaire des messages.

J'utiliserai ensuite queryOrderedByChild('negativeTimestamp') pour récupérer les messages dans un observeSingleEvent, puis j'aurai un observateur childAdded pour gérer les messages qui sont envoyés une fois les appels initiaux effectués.

Dans la documentation de Firebase, il est dit que je peux obtenir le serveur valeur d'horodatage de cet extrait de code firebase.database.ServerValue.TIMESTAMP

Comment écrire ceci pour Swift 3?

6
Edward 4 avril 2017 à 12:56

2 réponses

Meilleure réponse

Tout d'abord, voyez la réponse liée dans les commentaires. Cette réponse repose sur le client pour générer un horodatage rendu négatif et écrit sur Firebase.

Si vous souhaitez que Firebase génère un horodatage, cela peut également être fait avec cette petite structure et ce morceau de code Firebase.

Jetons d'abord un coup d'œil à la structure

root
  parent_node
    -Y8j8a8jsjd0adas
       time_stamp: -1492030228007
  timestamp: 1492030228007

Ensuite, un peu de code pour créer et travailler avec cette structure:

Définissez une variable que nous pouvons utiliser dans notre classe qui fait référence à l'horodatage Firebase

let kFirebaseServerValueTimestamp = [".sv":"timestamp"]

Et une fonction qui ajoute un observateur au nœud d'horodatage:

func attachObserver() {

    let timestampRef = self.ref.child("timestamp")
    let parentNodeRef = self.ref.child("parent_node")
    var count = 0

    timestampRef.observe(.value, with: { snapshot in

        if snapshot.exists() {
            count += 1
            if count > 1 {
                let ts = snapshot.value as! Int
                let neg_ts = -ts
                let childNodeRef = parentNodeRef.childByAutoId()
                let childRef = childNodeRef.child("time_stamp")
                childRef.setValue(neg_ts)
                count = 0
            }
        }
    })

Et une fonction qui écrit un horodatage, provoquant ainsi le déclenchement de l'observateur qui crée des nœuds enfants dans le parent_node en fonction de l'horodatage Firebase

func doTimestamp() {
    let timestampRef = self.ref.child("timestamp")
    timestampRef.setValue(kFirebaseServerValueTimestamp)
}

Voici le résumé.

Dans la fonction attachObserver, nous attachons un observateur au nœud d'horodatage - ce nœud peut exister ou non, mais s'il ne le fait pas, il sera créé - continuez à lire. Le code de la fermeture est appelé chaque fois qu'un événement se produit dans le nœud d'horodatage.

Lorsque la fonction doTimestamp est appelée, elle crée et écrit un horodatage dans le nœud d'horodatage, qui déclenche ensuite l'observateur que nous avons attaché dans attachObserver.

Le code de la fermeture d'observation effectue les opérations suivantes:

Assurez-vous que l'instantané contient quelque chose, et si c'est le cas, incrémentez un compteur (plus d'informations à ce sujet dans un instant). Si le compteur est supérieur à 1, obtenez l'horodatage sous forme d'entier à partir de l'instantané. Ensuite, créez-le négatif et réécrivez-le dans Firebase en tant qu'enfant de parent_node.

Comment cela s'appliquerait-il chaque fois que vous souhaitez horodater un nœud enfant avec un horodatage généré par Firebase mais une valeur négative pour le chargement / tri inversé - ce qui répond à la question OP.

Le gotcha ici est que quand cela arrive

    timestampRef.setValue(kFirebaseServerValueTimestamp)

Il écrit en fait deux fois sur le nœud, ce qui entraînerait l'appel du code du plus proche deux fois.

Peut-être qu'un Firebaser peut expliquer cela, mais nous devons ignorer le premier événement et capturer le second, qui est l'horodatage réel.

Ainsi, le premier événement amènera l'observateur plus près du feu, faisant count = 1, qui sera ignoré en raison de l'instruction if.

Ensuite, le deuxième événement se déclenche, qui contient l'horodatage réel, et c'est ce que nous utilisons pour rendre négatif et écrire sur Firebase.

J'espère que cela aidera l'OP et les commentateurs.

3
Jay 12 avril 2017 à 21:30

Que ce soit pour Swift ou non, une autre solution conceptuelle consiste à s'appuyer sur la valeur de décalage horaire du serveur de Firebase.

Ce n'est pas aussi précis que firebase.database.ServerValue.TIMESTAMP, mais la différence se situe généralement en quelques millisecondes. L'avantage est qu'il vous permet de créer un horodatage négatif sur le client sans avoir à mettre à jour votre nœud Firebase deux fois.

Vous récupérez la valeur de décalage horaire du serveur lorsque vous en avez besoin à partir de Firebase, générez l'horodatage négatif sur le client, puis enregistrez votre objet dans Firebase une fois.

Voir: https://groups.google.com/forum/#!topic/ Firebase-talk / EXMbZmyGWgE https://firebase.google.com/docs/database/ ios / offline-capabilities # clock-skew (pour iOS). https://firebase.google.com/docs/database/ Web / offline-capabilities # clock-skew (pour le Web).

var offsetRef = firebase.database().ref(".info/serverTimeOffset");
offsetRef.on("value", function(snap) {
  var offset = snap.val();
  var negativeTimestamp = (new Date().getTime() + offset) * -1;
});
2
Vitali Kniazeu 24 avril 2017 à 16:37