Set Firebase Timestamp to 2 weeks from today in Node.js Cloud Functions

Viewed 568

I'm trying to store a document in my Firebase Cloud Firestore which has two Timestamp fields: purchaseDate and expirationDate.

purchaseDate is the current date, and expirationDate is 2 weeks from current date.

I am using a post Cloud Functions request to set the doc.

I was able to achieve the current date (purchaseDate) like this:

const purchaseDate = admin.firestore.Timestamp.now();

But I can't figure out how to achieve a Timestamp for 2 weeks from current date.

I've tried to achieve it in several ways, including this exmaple, but nothing worked:

admin.firestore.Timestamp.fromDate(purchaseDate + 12096e5); //12096e5 = 2 weeks in ms

Any idea how can I achieve it?

Thank you very much!

2 Answers

One possible method, just using Timestamp's constructor and adding the correct number of seconds to purchaseDate:

const TWO_WEEKS_IN_SECONDS = 14*24*60*60

const purchaseDate = admin.firestore.Timestamp.now()
const expirationDate = new admin.firestore.Timestamp(
    purchaseDate.seconds + TWO_WEEKS_IN_SECONDS,
    purchaseDate.nanoseconds)

console.log(purchaseDate.toDate())
console.log(expirationDate.toDate())

Its up to you, of course, if carrying over the nanoseconds value is critical or not.


Your immediate problem is that fromDate wants a Date object, not a Firestore Timestamp. If you really want to go via the Date object, this can work for you too (note this will reduce your precision to milliseconds from nanoseconds):

const TWO_WEEKS_IN_MS = 1000*TWO_WEEKS_IN_SECONDS
const twoWeekOutDate = new Date();
twoWeekOutDate.setTime(purchaseDate.toDate().getTime() + TWO_WEEKS_IN_MS)
const alternative = admin.firestore.Timestamp.fromDate(twoWeekOutDate)

console.log(alternative.toDate())

Do keep in mind that this entire approach is only really secure if (as you are doing) it happens inside a secure context such as Cloud Functions. Though the same general approach would work client side, there are additional security considerations, as Frank describes in their answer.

While the approach in robsiemb's stores the correct value, it uses a client-side timestamp to do so. This means it can be manipulated by malicious users, if you don't properly protect against that.

This may be totally fine in your use-case, but I want to leave some additional thoughts and options:

  1. When allowing the client-side code to determine the timestamp, use Firebase's server-side security rules to ensure that the stored dates are in a reasonable range.

    For example, you could use request.time in the rules to ensure the field is roughly two weeks from now. This ensures that a malicious user can't set their own expiration date to something much longer or shorter than what you want.

  2. An alternative is to store the actual creation date as a server-side timestamp, and store the expiration interval separately. This typically makes validating the data easier, but makes querying for expired data slightly trickier as you have to query for both fields.

  3. Another alternative is to have the client write the creation date as a server-side timestamp, and then have a Cloud Function update the document with an expiration timestamp based on that.

Related