How would you write a method to convert all Firestore Timestamps in a snapshot to JavaScript Dates?
For example, a snapshot from a posts
collection might return a couple Firestore Timestamps (createdDtTm
, modifyDtTm
):
[ { text: 'My new post', uid: 'nzjNp3Q', createDtTm: Timestamp { seconds: 1596239999, nanoseconds: 999000000 }, modifyDtTm: Timestamp { seconds: 1596239999, nanoseconds: 999000000 }, }, { text: 'Another post', uid: 'nzjNp3Q', createDtTm: Timestamp { seconds: 1596239999, nanoseconds: 999000000 }, modifyDtTm: Timestamp { seconds: 1596239999, nanoseconds: 999000000 }, }, ]
Converting the individual dates is simple enough by mapping over the array and using the toDate() method for each Timestamp (e.g., createDtTm.toDate()
)
But what is a more generalized approach for converting these two (or any any arbitrary number of) Firestore timestamps, without explicitly specifying the Timestamp fields?
For instance, do Firestore Timestamps have a unique type that could be used for identification? Would an assumption of naming conventions be required (e.g., field name contains DtTm
)? Other?
Previous questions answer how to convert a single Timestamp or a single timestamp in multiple documents in a snapshot. But I haven’t found a generalized approach for converting all Timestamps within a snapshot when multiple Timestamps exist. More specifically, I’m interested in an approach for use within a React Provider
that would pass JavaScript dates (not Firestore Timestamps) to its Consumers
, while also not creating a dependency to update the Provider each time a new Timestamp field is added to the data model / collection.
Advertisement
Answer
I don’t think there is any global method for this, but I think its easy to create a function that will analyze snapshot and change it. It’s not very complicated. In node.js I have done it like this:
function globalToData (snapshot) { for (const field in snapshot) if (snapshot[field] instanceof Firestore.Timestamp) { snapshot[field] = snapshot[field].toDate() } else if (snapshot[field] instanceof Object) { globalToData (snapshot[field]); } return snapshot; };
if you get DocumentSnapshot
as ex. snap you can call it like:
globalToData(snap.data())
This should convert all Timestamps in all levels of Document snapshot ( I tested to 3rd level of nesting mixed map and array). We do not have your solution, but you can implement this somewhere in the middle of your app.