Date format for Firebase Firestore - javascript

Here's my problem : I want to send a timestamp to a firestore document. I was previously using a package called "react-native-datetime-picker", which returned a UNIX Epoch timestamp which I would directly send to firestore using :
startsAt: new firebase.firestore.Timestamp(startsAt, 83000000),
endsAt: new firebase.firestore.Timestamp(endsAt, 83000000),
(startsAt and endsAt being the timestamps). This worked and would send a timestamp to firestore, however, due to the fact that on Android you can only choose either date or time to pick and not both simulteanously, I am now using a packaged named "react-native-modal-datetime-picker" which allows me to pick both. Now this package returns a fully-fletched date in this format :
2021-03-20T18:25:00.000Z
When I try to send this to firestore, it doesn't work while saying : FirebaseError: Timestamp seconds out of range.
So I am guessing that I'm trying to send a non-conventional format of date to Firestore. Is there any way to change this date to a timestamp ? Or is there another workaround for this situation ? Thanks in advance !

I managed to send the date to Firestore using the getTime() function :
startsAt: new firebase.firestore.Timestamp(Math.round(startsAt.getTime() / 1000), 83000000),
getTime() transforms your date into an epoch timestamp in milliseconds, which you divide by 1000 to get in seconds and make sure Firestore stores it as a timestamp. You have to round it, as Timestamp() can't take decimals as parameters.

const timestamp = firebase.firestore.FieldValue.serverTimestamp();
Did you try this method, this is built-in firestore method and work properly across the all timestamps
Reference : https://firebase.google.com/docs/reference/js/firebase.firestore.FieldValue

Related

Cloud Firestore How to subtract hour from Timestamp

I am able to get the timestamp using this line in my index.js.
var now = admin.firestore.Timestamp.now();
I just want the timestamp that's 1 hour before now.
I've tried this and hasn't worked.
var old = now(now.seconds-1*60*60,milliseconds);
Also tried but it returns just the seconds instead of a timestamp
var old = admin.firestore.Timestamp.now().seconds - 1*60*60;
Any ideas on how to get the timestamp of an hour before?
Firestore's Timestamp class doesn't offer the ability to do "date math". You should do any date math using a native date type for your language, then convert that to a Timestamp when you're done.
Since you tagged this JavaScript, you could use a normal Date object to do the math:
const date = new Date(Date.now() - 60*60*1000)
The convert that to a Timestamp with Timestamp.fromDate():
const timestamp = admin.firestore.Timestamp.fromDate(date)

Use moment.js to change the timezone on a datetime stamp, without changing the time

I am migrating event data from an old SQL database to a new Mongo database, using NodeJS. However, whoever set up the SQL database created all of the dates for the events, made the times in PST/PDT, but the database believes they are in UTC time.
For Example:
A date from the SQL database may be: 23-APR-10 which MomentJS shows as: 2010-04-23T21:00:00Z when 21:00:00 is the PST time.
Is it possible to use pure JavaScript/MomentJS/NodeJS or a different npm module to change the timezone on the DateTime string without modifying the time (i.e. 2010-04-23T21:00:00Z would become 2010-04-23T21:00:00-8:00)?
PS. Even though the SQL database only shows DD-MMM-YY but returns a DateTime string when I query it.
Following the line of inquiry in the question comments, it seems your problem is that due to the timezone mishap, the timestamps stored in the db are stored without the timezone offset, and since your desired timezone is PST (UTC-8hours), the timestamps are 8 hours ahead, for instance, what should have been 2010-04-23T13:00:00Z has become 2010-04-23T21:00:00Z.
So what needs to be done here is that the utc offset for your desired timezone needs to be obtained and added to the date.
The offset in your case is known (-8 hours). However, we can fetch the correct offset of any desired timezone from the moment-timezone library.
const moment_timezone = require('moment-timezone');
//a sample timestamp you're getting from your db
const myDateObj = new Date("2010-04-23T21:00:00Z");
//timezone for PST as understood by moment-timezone
const myMomentTimezone = "America/Los_Angeles";
//offset for your timezone in milliseconds
const myTimezoneOffset = moment_timezone.tz(myMomentTimezone).utcOffset()*60000;
//perfom the correction
const getCorrectedDateObj = (givenDateObj) => new Date(givenDateObj.valueOf() + myTimezoneOffset);
console.log(getCorrectedDateObj(myDateObj));
You may notice that we are actually changing the timestamp, because the given timestamp and the requried timestamp are, due to the nature of the error, essentially different timestamps. Moment-timezone is only being used here to fetch the offset, it's not used to "convert" anything.
Anuj Pancholi's answer is correct, however; the old SQL database I'm using seems to have a lot of quirks, so I had to modify his answer to get my code working.
My Solution:
function getCorrectedDateObj(myDateObj){
const timezoneOffset = momentTimeZone.tz(timezone).utcOffset() * 60000;
const dt = new Date(myDateObj.valueOf() + timezoneOffset / 2);
dt.setHours(dt.getHours() + 12);
}

Type(Java)Script, how to create Timestamp

I am pulling in some data from a Firebase database, and I need to run some processing on it and then return it in the same format. For the most part this is not too bad, however when I pull the Date of Birth field it is sent to me in a Timestamp format as shown here:
This is then being converted into a date, everything that needs to be done is done to it, and I am then running the following code on the date format to turn it back into a timestamp.
updateData['dob'] = new Date(newUserDob).getTime();
This works and gets me the exact same value as I would be getting from the timestamp, however when I create it it is in this format
I have tried using:
var tStamp = new Timestamp('seconds', 1571184000000);
However this produces a timestamp of the format
Timestamp {value: 'seconds', timestamp: 1571184000}
Which is also not what I was getting originally.
Does anyone know how to just create a timestamp of the format shown in the first image? Thank you.
Edit: The second picture is showing nanoseconds instead of seconds. That was a bug at the time when the picture was taken, but rest assured the value is 1571184000.
{seconds: new Date(newUserDob).getTime(), nanoseconds: 0}
Ok, I figured it out eventually.
It was specifically because I was using Firebase to store the timestamp.
So I was able to recreate the timestamp format with:
firestore.Timestamp.fromDate(new Date(newUserDob));

How to get atomic clock with JavaScript?

I want to create JavaScript countdown, but I have to use atomic clock (non local PC time).
I find the http://worldclockapi.com/api/json/est/now, which gets you a JSON.
There is a property currentFileTime (timestamp), but not UNIX timestamp.
How to convert this timestamp to UNIX timestamp, get the Date Object and check Date, Hours, Minutes and Seconds?
Thanks
Just pick a timezone and call that:
With a call to http://worldtimeapi.org/api/timezone/Europe/London.json
You will get a json object with a unix time like here:
let result = {"week_number":29,"utc_offset":"+01:00","utc_datetime":"2019-07-15T11:44:07.720355+00:00","unixtime":1563191047,"timezone":"Europe/London","raw_offset":0,"dst_until":"2019-10-27T01:00:00+00:00","dst_offset":3600,"dst_from":"2019-03-31T01:00:00+00:00","dst":true,"day_of_year":196,"day_of_week":1,"datetime":"2019-07-15T12:44:07.720355+01:00","client_ip":"194.153.217.248","abbreviation":"BST"}
// result["unixtime"] => 1563191047

Convert date object to Firestore timestamp

I'm trying to convert a date object to a Firestore timestamp.
var dateOBJ = new Date();
var timeStamp = new firebase.firestore.Timestamp(dateOBJ);
This gives me an error:
Uncaught Error: Timestamp seconds out of range: Sun Dec 09 2018 11:37:05 GMT+0100
I tried converting the date object to seconds first by using .getTime() / 1000, but it's still out of range.
The timestamp is gonna be the expiration date for an url, so I need to add some time to it.
There are two ways of setting a date field in Cloud Firestore:
You specify a Date value for the field, in which case you fully determine what date is written.
You specify the firebase.firestore.FieldValue.serverTimestamp(), in which case the server writes the current date.
There is no way in the API to combine these two options, you either use one or the other.
Since you comment that you want to store the timestamp and an offset, that is also what I'd store:
a timestamp field that you let the server populate with firebase.firestore.FieldValue.serverTimestamp().
a offset field, that you populate from the app with the offset in days/hours.
That way you can reconstitute the effective expiration timestamp by combining the two fields.
You could even add a third field that stores the expiration timestamp, but that will require an extra write operation. I'd typically do this in Cloud Functions, to ensure you keep full control over the field and clients can't spoof it. If you don't do it in Cloud Functions, consider writing security rules that validate that the value if the calculated field is indeed the result of that calculation.
You won't get a consistent server side timestamp with a JavaScript date. Instead, send the server timestamp from the SDK:
const timestamp = firebase.firestore.FieldValue.serverTimestamp()
If you still want to set the timestamp as a Date you can just pass new Date() to Firestore and it will be saved as a timestamp.
Frank is right about setting timestamps into firestore.
If you want to check that timestamp on the front end afterwards you need to use .toDate on the timestamp object returned from firestore to turn it back into a JS date.

Categories

Resources