Actuellement, la version Google de ServerValue.TIMESTAMP
Renvoie {".sv":"timestamp"}
Qui est utilisé comme directive pour Firebase pour remplir ce champ avec l'horodatage du serveur une fois que vous avez enregistré les données sur le serveur Firebase.
Cependant, lorsque vous créez vos données côté client, vous ne disposez pas encore de l'horodatage réel (c'est-à-dire, utilisez-le comme date de création). Vous n'aurez accès à l'horodatage qu'après la sauvegarde initiale et la récupération qui en résulte, ce qui - j'imagine - est parfois trop tard et pas très élégant.
Avant Google:
Mise à jour: Ignorez cette section car elle est incorrecte - J'ai mal compris les exemples. ServerValue.TIMESTAMP
Renvoyait toujours le {".sv":"timestamp"}
.
Autant que je sache dans Firebase pré-google, il semblait y avoir un horodatage généré par le serveur disponible qui vous permettait d'acquérir l'horodatage réel:
import com.firebase.client.ServerValue;
ServerValue.TIMESTAMP // eg. 1466094046
Questions:
Remarque:
Je n'envisage pas d'utiliser new Date()
côté client car j'ai lu que ce n'est pas sûr, mais veuillez partager vos pensées si vous pensez différemment.
Lorsque vous utilisez le ServerValue.TIMESTAMP
constante dans une opération d'écriture, vous dites que le serveur de base de données Firebase doit déterminer l'horodatage correct lorsqu'il exécute l'opération d'écriture.
Disons que nous exécutons ce code:
ref.addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println(dataSnapshot.getValue());
}
public void onCancelled(DatabaseError databaseError) { }
});
ref.setValue(ServerValue.TIMESTAMP);
Cela s'exécutera comme suit:
ServerValue.TIMESTAMP
Si vous utilisez ChildEventListener
au lieu d'un ValueEventListener
, le client appellera onChildAdded
à l'étape 3 et onChildChanged
à l'étape 8.
Rien n'a changé dans la façon dont nous générons le ServerValue.TIMESTAMP
depuis que Firebase a rejoint Google. Le code qui fonctionnait auparavant continuera de fonctionner. Cela signifie également que le première réponse que vous avez liée est un moyen valide de le gérer.
Je le fais un peu différemment.
Solution 1: Push()
méthode dans POJO
Comme je ne veux pas encombrer mes POJO avec des getters ou des propriétés étranges, je définis juste une méthode Push()
à l'intérieur de mes POJO qui ressemble à ceci:
/**
* Pushes a new instance to the DB.
*
* @param parentNode `DatabaseReference` to the parent node this object shall be attached to
*/
fun Push(parentNode: DatabaseReference) {
parentNode
.Push()
.apply {
setValue(this@Pojo)
child(Pojo.CREATED_AT_KEY).setValue(ServerValue.TIMESTAMP)
}
}
Ensuite, je peux simplement créer une instance de POJO et appeler Push()
dessus qui remplit correctement la propriété time de création.
Cela rend le POJO un peu moins clair et implique une logique qu'un POJO ne devrait pas connaître. Cependant, l'utilisation d'annotations et/ou de transtypages @Exclude
Comme indiqué dans certaines réponses ici nécessite également la connaissance du mécanisme de stockage.
Solution 2: Aide ou extension DatabaseReference
(Kotlin)
Pour surmonter cela, vous pouvez bien sûr également créer une méthode pushTask(task: Task)
dans une aide ou - si vous utilisez Kotlin - une méthode d'extension pour par exemple DatabaseReference
qui pourrait ressembler à ceci:
fun DatabaseReference.Push(pojo: Pojo) {
Push()
.apply {
setValue(pojo)
child(Pojo.CREATED_AT_KEY).setValue(ServerValue.TIMESTAMP)
}
}
En y regardant maintenant, j'en viens à penser que j'aime plus la deuxième approche ( si J'ai Kotlin à ma disposition - je n'aime pas les assistants). Mais ce n'est probablement qu'une question de goût. ;)