97 votes

Comment obtenir le timestamp du serveur dans les fonctions Cloud pour Firebase ?

Je sais que vous pouvez obtenir le timestamp du serveur dans le web, iOS et Android - mais qu'en est-il des nouvelles Cloud Functions pour Firebase ? Je n'arrive pas à savoir comment obtenir le timestamp du serveur là-bas ? Le cas d'utilisation est que je veux horodater un e-mail à son arrivée.

Sur le web, c'est Firebase.database.ServerValue.TIMESTAMP

Mais cela ne semble pas être disponible dans l'interface du serveur de nœuds de fonctions ?

Je pense qu'il est tard et que je peux manquer le point ici...

EDIT

Je m'initialise comme ceci

admin.initializeApp(functions.config().firebase);
const fb = admin.database()

Ensuite, il est appelé comme ça..

Firebase.database.ServerValue.TIMESTAMP

Mais, cela vient d'une intégration côté client. Dans Functions, Firebase n'est pas initialisé de cette manière. J'ai essayé

admin.database().ServerValue.TIMESTAMP

et

fb.ServerValue.TIMESTAMP

0 votes

Autant que je sache, ServerValue.TIMESTAMP est également disponible dans les fonctions Cloud pour Firebase. Pouvez-vous partager le code minimal qui reproduit le problème ?

0 votes

Salut @FrankvanPuffelen - J'ai modifié l'original avec un exemple de mon initialisation et ce qui ne fonctionne pas.

138voto

Frank van Puffelen Points 16029

Étant donné que vous utilisez déjà le SDK d'administration, la syntaxe correcte pour écrire un horodatage côté serveur dans la base de données en temps réel est :

admin.database.ServerValue.TIMESTAMP

Cela renvoie une valeur dite sentinelle, que le serveur de la base de données reconnaît comme une instruction pour écrire l'horodatage actuel.


Si vous utilisez Cloud Firestore (au lieu de la base de données en temps réel dont il est question ici), l'incantation correcte est :

admin.firestore.FieldValue.serverTimestamp()

Si cela ne fonctionne pas pour vous, n'oubliez pas de consulter la documentation de référence pour les dernières mises à jour et exemples.

1 votes

C'est la réponse simple que je cherchais - merci @frank-van-puffen

18 votes

Comment imprimer un horodatage en millisecondes avec ceci? admin.database.ServerValue.TIMESTAMP renvoie un objet { '.sv': 'timestamp' }, que je crois être un espace réservé.

4 votes

C'est en effet un espace réservé. Pour obtenir la valeur réelle, écoutez l'emplacement que vous écrivez.

124voto

Paul Points 659

Si vous utilisez le SDK Firebase Admin, voici la syntaxe correcte :

2023

// Cloud Firestore
import { Timestamp } from 'firebase-admin/firestore'; 

// usage
Timestamp.now()

(2021-2022)

// Cloud Firestore
admin.firestore.Timestamp.now();

(Vérifié le 2019-08-27) :

const admin = require('firebase-admin');
// ou
// import * as admin from 'firebase-admin';

// Utilisation de Cloud Firestore
admin.firestore.FieldValue.serverTimestamp()

// Utilisation de la base de données en temps réel
admin.database.ServerValue.TIMESTAMP

1 votes

Fonctionne comme un charme :-) merci.

5 votes

Je pense que pour Cloud Firestore, cela doit être : admin.firestore.FieldValue.serverTimestamp()

1 votes

Firestore.FieldValue.serverTimestamp() ne fonctionne pas sur les fonctions firebase nodejs.

27voto

Spiral Out Points 394

Juste pour clarifier pour les lecteurs futurs:

admin.database.ServerValue.TIMESTAMP renvoie un objet non null et est une valeur de substitution pour auto-populer le timestamp actuel. Il ne contient pas le timestamp réel. La base de données remplacera cette valeur de substitution lors de l'exécution de la commande.

Si vous l'utilisez à l'intérieur d'un database.ref alors cela fonctionne comme vous vous y attendez et est la façon préférée d'entrer un timestamp :

var sessionsRef = firebase.database().ref("sessions");
sessionsRef.push({
startedAt: firebase.database.ServerValue.TIMESTAMP // ceci écrira 'startedAt: 1537806936331`
});

Mais si vous essayez de l'utiliser en dehors de la fonction de base de données (par exemple pour retourner l'heure actuelle ou effectuer des calculs), il renverra un objet que vous ne pourrez pas utiliser :

console.log(firebase.database.ServerValue.TIMESTAMP) // cela renverra un [object Object]

En savoir plus à ce sujet dans firebase.database.ServerValue et dans cette question SO.

Date.now() fonctionne très bien en dehors d'une fonction database si vous voulez l'utiliser pour un calcul ou toute autre utilisation générale.

console.log(Date.now()); // cela renverra 1537806936331

Ils utilisent tous les deux le temps Unix qui est le nombre de secondes écoulées depuis 00:00:00 Temps Universel Coordonné (UTC), le jeudi 1er janvier 1970, et est indépendant du fuseau horaire. C'est le même nombre sur le client et sur le serveur (... ou presque :-). Voir le temps Unix.

1 votes

Meilleure réponse pour un débutant! :)

0 votes

Bonjour, quand j'écris un horodatage et le sauvegarde dans la base de données, j'obtiens ce message dans les fonctions cloud : 'La charge utile de messagerie contient une valeur invalide pour la propriété "notification.timestamp". Les valeurs doivent être des chaînes.' @SpiralOut

0 votes

@DevAS Essayez de publier une nouvelle question avec plus de détails sur votre code. Mais Notification.timestamp n'est pas un mot-clé de la base de données firebase. Peut-être utiliser firebase.database.ServerValue.TIMESTAMP

16voto

Bob Snyder Points 24996

Je suis moi-même novice en node.js, mais Date.now() fonctionne dans mes tests.

Éditer

J'ai mal compris votre question - je n'avais pas réalisé que vous vouliez horodater les données que vous stockiez dans la base de données Firebase. Je pensais que vous vouliez simplement obtenir l'heure sur le serveur qui exécutait votre fonction cloud. Si vous voulez horodater un e-mail reçu stocké dans la base de données Firebase, alors utiliser admin.database.ServerValue.TIMESTAMP est sans aucun doute la meilleure approche.

Juste pour mon propre apprentissage, j'ai écrit la fonction suivante pour voir comment les horaires se comparent. Je m'attendrais à ce que les horaires sur le serveur de la fonction cloud et le serveur de base de données soient synchronisés avec une référence de temps très précise. Lorsque j'exécute cette fonction, le timestamp de la base de données est généralement dans les centaines de millisecondes de la valeur de Date.now(). Le timestamp de la base de données étant un peu plus tard est raisonnable, étant donné qu'il faut un certain temps à la fonction cloud pour se connecter à la base de données et effectuer l'écriture.

exports.timeTest = functions.database.ref('/test/trigger')
    .onWrite(event => {

        const now= Date.now();
        console.log('now=', now);

        const timeVals = {
          dateNow : now,
          serverTimestamp : admin.database.ServerValue.TIMESTAMP
        };

        return event.data.ref.parent.child('times').update(timeVals);
    });

0 votes

Et Date.now() obtient-il l'heure du serveur node, ou l'heure de l'ordinateur du client pour effectuer son calcul? Ou utilise-t-il une horloge normalisée? Si je définis l'heure de mon ordinateur à un moment donné, Date.now() la modifiera-t-il à un autre moment et Date.now() obtiendrais-je alors deux résultats différents?

1 votes

@JustinHandley: Mise à jour de ma réponse. Date.now() est l'heure sur le serveur exécutant votre fonction cloud. Il est complètement indépendant de l'heure sur n'importe quel ordinateur client.

3 votes

Admin.database.ServerValue.TIMESTAMP est la seule solution acceptable lorsque vous utilisez les règles Firebase pour tester que this == now (Bolt)

16voto

Dépend du cas d'utilisation

cas 1

vous souhaitez définir le champ du document sur le timestamp du serveur

L'exemple peut être

utilisateur {
  email: "exemple.com",
  lastUpdated: admin.firestore.FieldValue.serverTimestamp(),
}

Note serverTimestamp renvoie un objet non nul et est une valeur fictive pour auto-remplir le timestamp actuel. Il ne contient pas le timestamp réel. La base de données remplacera cette valeur fictive lorsqu'elle exécutera la commande

*Renvoie un sentinelle utilisé avec set(), create() ou update() pour inclure un timestamp généré par le serveur dans les données écrites.

@return Le sentinelle FieldValue à utiliser dans un appel à set(), create() ou update().*

cas 2

vous souhaitez utiliser le timestamp du serveur pour la logique de vos fonctions

if (currentTime == 6pm) // TODO: envoyer des notifications push
else // TODO: ne rien faire

pour cela, vous voudrez peut-être faire quelque chose comme

admin.firestore.Timestamp.now() ou admin.firestore.Timestamp.fromDate(new Date())

bonne lecture: https://bigcodenerd.org/firebase-server-timestamp-cloud-functions/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X