I'm really scratching my head over dates in Firebase - I have a record in my db where I have saved a date (start) - The date is set to be the start of day on September 11:
All good, now when I do a query in my app where I want to find the record it works great with the following code:
try {
const startToToday = startOfDay(new Date());
const startTimestamp = Timestamp.fromDate(startToToday)
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const test = await queryDocuments('client_events', 'start', startTimestamp.toDate());
console.log('This returns a record', test);
} catch (e) {
throw new Error('error ' e);
}
However, when I want to do the same in a Firebase Cloud Function, I'm not getting a match, meaning that it does not believe the dates have a match - But I'm basically doing the same (I've removed some code to focus on the relevant parts)
export const sendDailyClientEventMails = functions.pubsub.schedule("0 0 * * *").onRun(async () => {
try {
const events: ClientEvent[] = [];
const userIds: string[] = [];
const startOfToday = startOfDay(new Date());
functions.logger.log("startOfToday", startOfToday);
const todayTimestamp = admin.firestore.Timestamp.fromDate(startOfToday);
functions.logger.log("todayTimestamp", todayTimestamp);
functions.logger.log("toDate", todayTimestamp.toDate());
// eslint-disable-next-line max-len
const clientEventsCollection = db.collection("client_events") .where("start", "==", todayTimestamp.toDate());
// eslint-disable-next-line max-len
const clientEvents = await clientEventsCollection.get();
// eslint-disable-next-line max-len
functions.logger.log("all client events", JSON.stringify(clientEvents.docs)); //This is empty????
} catch (e) {
functions.logger.log("Error in function: ", e);
return null;
}
return null;
});
Now, if I try to do some logging of the actual event and the "start" date in the function, it returns this in seconds:
event.start.seconds -> 1662847200
When running this through an epoch converter, it says the date is (which does not make sense?):
GMT: Saturday, September 10, 2022 10:00:00 PM
And when logging my time (Start of 11 september) - I get this in seconds:
getStartOfToday Timestamp { _seconds: 1662854400, _nanoseconds: 0 }
When running this through the epoch converter it gives me the date I would expect:
GMT: Sunday, September 11, 2022 12:00:00 AM
When comparing the seconds from firebase and my current date, they do not match, even though the saved record in Firebase indicates it is the same dates (see the screenshots)?
It's driving me crazy, and I must be overlooking something? Is it something with the server running the cloud function that does not match or what is it?
Basically, what I want is to find all events matching the current date, which works clientside, but not when running in a cloud function?
CodePudding user response:
Default timezone for Scheduled Cloud Functions is America/Los_Angeles
. So midnight there is 7 AM GMT (or 8 depending on daylight savings). You can specify the timezone for your scheduled function as shown below:
exports.functionName = functions.pubsub.schedule('0 0 * * *')
.timeZone('UTC') // <-- Timezone
.onRun((context) => {
return null;
});
The query works on client end because there your time is based on your Timezone.
Using libraries like Luxon might make it easier to deal with with timezones.