I have a firestore project that manages user bookings and includes the cloud function below that is set to run daily at midnight. The function identifies flags for recurring bookings and creates a new booking (firestore document) for the same time/day the following week.
This function runs correctly probably 5 or 6 days a week but randomly doesn't run some days. It's called because I see the 'Daily Recurring Bookings Started...' log but no new documents are created.
If I then change the time on the pubsub schedule for it to run again later n the day it works...
No errors in the logs...
Struggling to understand why the function seems to be killed on some occasions....
// Scheduled function to create repeat bookings each day.
exports.createRecurringBooking = functions.pubsub
.schedule('01 00 * * *')
.timeZone('Europe/London') // Runs in London Timezone
.onRun((context) => {
const firestore = admin.firestore;
const db = admin.firestore();
console.log('⏰ Daily Recurring Bookings Started....');
// Define current day and next day with 00:00 start Time
const today = new Date(new Date().setHours(0, 0, 0, 0));
const todayUnix = dayjs(today).valueOf();
const tomorrowUnix = dayjs(today).add(1, 'day').valueOf();
const todayTimestamp = firestore.Timestamp.fromMillis(todayUnix);
const tomorrowTimestamp = firestore.Timestamp.fromMillis(tomorrowUnix);
// Get bookings from firestore for current day with no end date
db.collection('bookings')
.where('startTime', '>=', todayTimestamp)
.where('startTime', '<', tomorrowTimestamp)
.where('isRecurring', '==', true)
.where('recurringCount', '==', -1)
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
const startTime = dayjs(doc.data().startTime.toDate());
const newStartTime = dayjs(startTime).add(7, 'day');
const newStartTimeTimestamp = firestore.Timestamp.fromMillis(
dayjs(newStartTime).valueOf()
);
newRecurringBooking = {
bookingDetails: doc.data().bookingDetails,
channel: doc.data().channel,
createdAt: firestore.Timestamp.now(),
isRecurring: true,
start: doc.data().start ? doc.data().start : newStartTimeTimestamp,
location: doc.data().location,
recurringCount: doc.data().recurringCount,
recurringDescription: doc.data().recurringDescription
? doc.data().recurringDescription
: '',
recurringWeek: doc.data().recurringWeek + 1,
startTime: newStartTimeTimestamp,
status: 'confirmed',
studio: doc.data().studio,
user: doc.data().user,
};
db.collection('bookings')
.doc()
.set(newRecurringBooking)
.then(() => {
console.log(' ⭐ Recurring Booking created! ');
})
.catch((error) => {
console.error('Error Creating Booking: ', error);
});
});
})
.catch((error) => {
console.log(
`❌ ERROR when creating open ended recurring bookings! Error: ${error}`
);
});
// Get bookings from firestore for current day with end date
db.collection('bookings')
.where('startTime', '>=', todayTimestamp)
.where('startTime', '<', tomorrowTimestamp)
.where('isRecurring', '==', true)
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
const startTime = dayjs(doc.data().startTime.toDate());
const newStartTime = dayjs(startTime).add(7, 'day');
const newStartTimeTimestamp = firestore.Timestamp.fromMillis(
dayjs(newStartTime).valueOf()
);
// Only create new booking if sequence hasn't ended.
if (
doc.data().recurringWeek < doc.data().recurringCount &&
doc.data().recurringCount > 0
) {
newRecurringBooking = {
bookingDetails: doc.data().bookingDetails,
channel: doc.data().channel,
createdAt: firestore.Timestamp.now(),
isRecurring: true,
location: doc.data().location,
recurringCount: doc.data().recurringCount,
recurringDescription: doc.data().recurringDescription
? doc.data().recurringDescription
: '',
recurringWeek: doc.data().recurringWeek + 1,
startTime: newStartTimeTimestamp,
status: 'confirmed',
studio: doc.data().studio,
user: doc.data().user,
};
db.collection('bookings')
.doc()
.set(newRecurringBooking)
.then(() => {
console.log(' ⭐ Booking created! ');
})
.catch((error) => {
console.error('Error Creating Booking: ', error);
});
}
});
})
.catch((error) => {
console.log(
`❌ ERROR when creating recurring bookings with end date! Error: ${error}`
);
});
return null;
});