grahappa
grahappa

Reputation: 41

How do I create document in Firestore with reliable timestamps?

How are any firestore timestamps considered valid coming from the client SDK when they can't be set on the firestore server itself?

Is it not true that an authenticated user could hack his own timestamps? What is the point of the client sdk offering a timestamp data type if they can't be reliable? Does that mean we have to use the Firebase Admin sdk to create user data on signup or anything else that requires a timestamp? What developer doesn't put a timestamp on every collection of data? If so, what is the point of the client sdk? Clearly I'm missing something.

i have tried this from the firebase client sdk with no error or timestamp;

myFirestoreReference.ref.set({
  userId: firebaseUserCredential.user.uid,
  created: this.$fireStore.FieldValue.serverTimestamp()
})

The above code successfully creates the 'userId' but no the 'created' timestamp.

Upvotes: 0

Views: 368

Answers (2)

grahappa
grahappa

Reputation: 41

My answer is to use the following code on my server inside an api using the Firebase Admin sdk. Here is an example of what I was looking for but never found to date. The code listed below demonstrates the use of...

Firebase Admin sdk => FireStore

It's reliable because it's comes from my server via the Firebase Admin sdk and not the Firebase Client sdk, in addition the serverTimestamp() is set by the FireStore server and not my webserver(via 'new Date()') or the client machine that makes the original request. I was able to realize this answer by deducing from examples of...

Firebase Client sdk => FireStore https://firebase.google.com/docs/firestore/manage-data/add-data

and

Firebase Admin sdk => Firebase Auth https://firebase.google.com/docs/auth/admin/manage-users

var admin = require('firebase-admin');

admin.initializeApp({
  credential: admin.credential.cert({
    projectId: MY_FIREBASE_PROJECT_ID, 
    clientEmail: MY_FIREBASE_CLIENT_EMAIL,
    privateKey: MY_FIREBASE_PRIVATE_KEY,
  }),
  databaseURL: MY_FIREBASE_DATABASE_URL
});


var serverTimestamp = admin.firestore.FieldValue.serverTimestamp()    

admin.firestore().collection('someFireStoreCollection').doc(someFireStoreCollectionId).update({
  someDateField: serverTimestamp
}).then(function() {
  console.log("Successfully updated FireStore");
}).catch(function(error) {
  console.log("Error updating FireStore:", error);
  throw(error)
});

Upvotes: 0

Doug Stevenson
Doug Stevenson

Reputation: 317342

You can check the validity of timestamps in security rules. This rules requires that the client provide the server timestamp token in the created field of a document being written to the "foo" collection:

match /foo/{id} {
    allow write: if request.resource.data.created == request.time;
}

request.time is the time that the request was received by Firestore, which is also the value implied by the token generated by serverTimestamp() on the client.

Upvotes: 2

Related Questions