80

I'm currently using Math.floor(Date.now() / 1000) to get the correct timestamp format to add into a document in Firebase, however, the timestamp gets inserted as a number, and not as a timestamp.

number

I would like to have it inserted as shown below (as a timestamp, not as a number).

enter image description here

Is this possible?

Arjen de Jong
  • 1,051
  • 1
  • 7
  • 15
  • 1
    Check **[this](https://stackoverflow.com/questions/53336061/how-to-save-date-in-angular-as-a-timestamp-to-firestore)** out. – Alex Mamo Nov 26 '18 at 14:05
  • 1
    You can simply use the servervalue: [documentation](https://firebase.google.com/docs/reference/js/firebase.database.ServerValue) – André Kool Nov 26 '18 at 14:05
  • Possible duplicate of [Converting milliseconds to a date (jQuery/JavaScript)](https://stackoverflow.com/questions/4673527/converting-milliseconds-to-a-date-jquery-javascript) –  Nov 26 '18 at 14:06
  • 2
    @E.Maggini This is not a duplicate of that question. This question is not about converting a timestamp to a date but about saving the timestamp in Firestore as a timestamp instead of a number. – André Kool Nov 26 '18 at 14:10
  • 1
    Thanks everyone, I'll checkout the [Timestamp documentation](https://firebase.google.com/docs/reference/js/firebase.firestore.Timestamp) for converting. I cannot use the `firebase.database.ServerValue.TIMESTAMP` value because some of the dates I'm using aren't the current dates. – Arjen de Jong Nov 26 '18 at 14:13
  • @AndréKool Maybe not a dupe strictly speaking but it would appear OP is trying to convert millis to date and it contains the answer he is looking for. https://jsfiddle.net/Lc0rpqe2/ –  Nov 26 '18 at 14:32

11 Answers11

131

You can simply use the following line:

var myTimestamp = firebase.firestore.Timestamp.fromDate(new Date());

.fromDate is a static method from the static Timestamp class from Firebase.

Ref: Firebase Timestamp Doc

Update:

For cloud functions look at JGuo's comment:

If you are writing cloud functions, it becomes admin.firestore.Timestamp.fromDate() – JGuo Jan 21 at 1:56

Sean Stayns
  • 4,082
  • 5
  • 25
  • 35
  • 3
    Thank you this is the simplest solution and exactly what I was looking for! For some reason the documentation I found said you passed the date in via the constructor not via a static method. – JCisar Feb 19 '19 at 04:41
  • 4
    Sending new Date() or Date.now() directly is totally enough. Firebase/Firestore handle the convertion to a timestamp on his own. Plus you can use moment.js to handle all your date manipulation – 1020rpz Aug 25 '19 at 08:47
  • 10
    if you are writing cloud functions, it becomes `admin.firestore.Timestamp.fromDate()` – Jack Guo Jan 21 '20 at 01:56
  • 1
    How to access this function in App Script? – Nehal Jun 02 '20 at 14:49
  • 1
    agreed that sending new Date() is enough, but Typescript wants a type - either Date or firebase.firestore.Timestamp (could use a union type but don't like to) – danday74 Aug 03 '21 at 16:49
  • I had to use firebase.default.firestore – Beanwah Aug 22 '21 at 02:34
  • If your object has logic in its constructor you can do a JSON.parse(JSON.stringify(myObject)) to remove that from the object prototype before sending to Firestore. This ultimately made the custom object error go way for me. – Beanwah Aug 22 '21 at 02:53
  • in the new firebase SDK, you can import the `Timestamp` directly, so use: `const datetime = Timestamp.fromDate(new Date())` – Biskrem Muhammad Aug 19 '23 at 17:16
20

If you want to store a field as a timestamp in Firestore, you'll have to send a JavaScript Date object or a Firestore Timestamp object as the value of the field.

If you want to use Date, simply say new Date(x) where x is the value in milliseconds that you were trying to add before.

If you want to use Timestamp, you would have to do more work to get that x converted into a combination of seconds and nanoseconds to pass to the constructor, as the documentation suggests.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
13

This is a bit old but just figure out how to do this in a Svelte project. I assume this would also work in a React project (sorry don't know much about Vue). The kicker is that I am using Web version 9.

import { Timestamp } from "@firebase/firestore";
let noteDate = Timestamp.fromDate(new Date());

Just for context... I am adding this new note object to the UI. When it was just a javascript date it worked fine with firebase but I could not call the required .toDate() without seeing an UI error.

<TimeAgo date={note.NoteDate.toDate()} />

So making this a firebase.Timestamp was my way of avoiding the UI error when calling .toDate on a javascript date object.

Brett
  • 786
  • 1
  • 8
  • 10
9

I solved it by using:

const created = firebase.firestore.Timestamp.fromDate(new Date()).toDate();

You have to import firebase from 'firebase/app' explicitly in your code.

import * as firebase from 'firebase/app'

Make sure your created or whatever constant is in type Date before actually being saved to firestore.

patelarpan
  • 7,188
  • 2
  • 20
  • 25
7

As i can see you are doing date added you would be better using the Server Timestamp and using the below security rule to enforce it.

Security Rules

allow create: if request.resource.data.date_added == request.time && 
              // other rules for the message body

Client side JS code

const message = {
    date_added: firebase.firestore.FieldValue.serverTimestamp();
}
Jack Woodward
  • 991
  • 5
  • 9
  • 2
    Not sure this would fit the OP's followup comments: "I cannot use the firebase.database.ServerValue.TIMESTAMP value because some of the dates I'm using aren't the current dates." – Jake Lee Nov 26 '18 at 14:50
  • Fair enough. This is more of a create rule and in that instance all the dates are new so you could use this. Then using an allow update rule that says you cant change its value as thats not when it was added. Then it would just be a case of updating historic data if it exists. – Jack Woodward Nov 26 '18 at 14:59
  • I agree that my wording for the date variable should be something else instead of 'date_added'. However I'm grateful for your answer as I might use it someday! – Arjen de Jong Nov 26 '18 at 15:06
6

To store a date / timestamp in Firestore, you need to send a Date object.

For example, with an existing date, set a field to: new Date("December 10, 1815")

Further information is available in the docs.

Jake Lee
  • 7,549
  • 8
  • 45
  • 86
  • 4
    In particular, `Date.now()` and `Date.parse()` return epoch numbers. Don't use them, instead `new Date()` and `new Date(...)`. – akauppi Mar 27 '20 at 12:43
3

The best way is to use the Timestamp class provided by Firebase

const {Timestamp} = require("firebase/firestore");

Then

Timestamp.fromDate(new Date())
Coder Gautam YT
  • 1,044
  • 7
  • 20
0

Late to the game here, but as I read the OP's question it specifically illustrates retaining the timezone offset. Since a timestamp lacks the offset, as the question was asked by the OP it looks like the honest answer is NO.

I have a related situation right now where I need a representation of a specific 'day' but I need the offset. A timestamp with 0s for h/m/s would be ideal except for the lack of offset. I am forced to either add a second field to store the offset, or to do something like a string:

'20200125-360'

Love to Code
  • 425
  • 1
  • 5
  • 16
-2

Use

 let lang = 'en-US' // you may use user's computer language: navigator.language || navigator.userLanguage
 let d = new Date(date);
 let options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour:"numeric", timeZone:'short' };
 firebase.database().ref('/thePathYouLikeToSave/date_added').set(d.toLocaleDateString(lang, options));

for more options of the date here the full details

Cappittall
  • 3,300
  • 3
  • 15
  • 23
-2

This question already have several answer but for the sake of simplicity I explaining it in my way

Kotlin code

val dateObject = Date()
val timestamp = Timestamp(dateObject)
AZIM MOHAMAD
  • 72
  • 11
-3

I found a solution thar worked for me when using firebase.firestore.FieldValue.serverTimestamp :

moment(createdAt.toDate().toISOString()).fromNow()