Firebase timestamp to javascript date format
If you’ve used Firebase and especially Firestore in your javascript (Angular in my case) project, you might have had the same problem as I have. Date and time in the Firestore are saved in their proprietary date format — called Timestamp.
Firestore timestamp is just a simple object with two properties — seconds and nanoseconds, which apparently has some advantages over “classic” date format.
A Timestamp represents a point in time independent of any time zone or calendar, represented as seconds and fractions of seconds at nanosecond resolution in UTC Epoch time.
It is encoded using the Proleptic Gregorian Calendar which extends the Gregorian calendar backwards to year one. It is encoded assuming all minutes are 60 seconds long, i.e. leap seconds are “smeared” so that no leap second table is needed for interpretation. Range is from 0001–01–01T00:00:00Z to 9999–12–31T23:59:59.999999999Z.
So where’s the problem?
Angular doesn’t recognise it as a date format. So if you do something like this:
you’ll get:
Angular’s date pipe can’t handle it either:
Fortunately Timestamp object comes with a method toDate(). So to make my example work, I have to change it this way:
Or even better, we can call it directly inside the typescript file ie. in our API service.
But…
In some cases it could get complicated to call this method, depends on the structure of your document. So an easy call which could look like this:
could become this:
or:
And that’s not elegant solution at all!
So i was searching for something, that will do it instead of me and I ended up with this little helper function, which will convert all timestamps in the object passed as an argument:
Only thing I need now, is to call this function wherever I need it, and it will take care of the whole object with its properties, inner array and map.
There’s one more thing…
I’ve decided to create an NPM package of it, so anybody could easily implement it, so here it is :)
All what it takes is import the package and…
return this.db.collection('my-collection').doc(id).snapshotChanges()
.pipe(
map(doc => convertTimestamps(doc.payload.data())
)
or better — as a RxJS pipe:
return this.db.collection('my-collection').doc(id)
.snapshotChanges().pipe(
map(doc => doc.payload.data()),
convertTimestampsPipe(),
);
Here is the reposity, don’t hesitate to contribute if you fell it’s missing something.