Run a cron job only once after a set time - firebase

I need to run a cron job to perform a specific cloud function after a set interval only once but a bit unsure of how to do it. Is there any way to do this through the current google cloud platform?

Update following our discussion below through comments:
If you want to "change a document in your Firestore database 2 hours after it has been created" you could do as follows:
When creating the document in Firestore, save the date/time of creation, e.g. with firebase.firestore.FieldValue.serverTimestamp()
Have an HTTP Cloud Function that you call regularly as explained below (every minutes? every 5 minutes?) and that, first, selects the documents that were created 2 hours ago (based on the saved timestamp) and then do the desired action on these docs.
If you want to trigger a Cloud Function through a cron job, note that you would normally do that through an HTTP Cloud Function, calling the Cloud Function URL via the cron job.
You can either use an external service like cron-job.org or you can use GCP's App Engine and Cloud Pub/Sub
See this video: https://www.youtube.com/watch?v=fEBPAMSk5_8
and this Blog post: https://firebase.googleblog.com/2017/03/how-to-schedule-cron-jobs-with-cloud.html
both from the Firebase team.
Finally note that recently GCP launched a new product, Cloud Scheduler, which can be used to call HTTP Cloud Functions.

Sorry for late answer. Once upon time, I am stuck with this issue too. You sure can schedule a job executed once at particular time. But, you must use multiple platform as Firebase Cloud Function has time limit to cron task. If you look at Quotas and limits document for Time Limit of Firebase, you can see that Firebase cloud functions have set time limits until they are canceled (540 seconds or 9 minutes). So you can't cron a job executed after more than 9 minute with cloud function. But you can use Heroku server to cron a job without paying. Unfortunately, Heroku apps sleep after 30 minutes if there is no task along the time interval. However, you can keep awake with external server such as cron-job.org. You can get unlimitedly your app awake by applying pinging to your Heroku app every minute less than 30 minutes. You can use node-schedule to cron a job executed once for all time by using this code there:
const schedule = require('node-schedule');
const date = new Date(2012, 11, 21, 5, 30, 0);
const job = schedule.scheduleJob(date, function(){
console.log('The world is going to end today.');
});
You can get current time or timestamp for Firestore and add time interval to current date to schedule as you desire. Dont forget to use timezone for it. You can use rule to set timezone like that:
const rule = new schedule.RecurrenceRule();
rule.dayOfWeek = [0, new schedule.Range(0, 6)]; //all days
rule.hour = req.body.hour;
rule.minute = req.body.minute;
rule.second = req.body.second;
rule.tz = "Europe/Istanbul"; // You can specify a timezone!
Here, you can get request from client side by fetching time specification from user. And use schedule job module for one time task like that:
const job = schedule.scheduleJob(rule, function(data) {
console.log("Job ran #", new Date().toString());
}.bind(null, dataFuture));
Here you can use user data with .bind() by entering variable just like dataFuture variable. If your users use native android platform, you can specify time interval by entering hour_of_day and minute as:
Date currentTime = Calendar.getInstance().getTime();
Locale aLocale = Locale.forLanguageTag("tr-TR");
Calendar calendar = Calendar.getInstance(aLocale);
calendar.setTime(currentTime);
calendar.add(Calendar.MINUTE, 1);
calendar.add(Calendar.HOUR_OF_DAY, 4);
Alternatively you can use Cloud Task platform. But it may be a bit hard to use.

Related

Using Firebase Cloud Functions to fetch data from api?

I have a use case where I want to call an API to fetch data twice without any trigger from the front-end and I'm wondering if firebase cloud functions are of any help in this regard.
Basically what I. want is, to get data from API (twice a day), store it in firestore and firebase storage, and call the firebase API from the front-end.
Please suggest me, if I should even consider firebase cloud functions for the task!
You can use Firebase Scheduled Cloud Functions that runs twice a day:
exports.scheduledFunctionCrontab = functions.pubsub.schedule('0 0,12 * * *')
.timeZone('America/New_York') // Users can choose timezone - default is America/Los_Angeles
.onRun((context) => {
console.log('This will be run every day at 00:00 AM and 12:00 PM Eastern!');
// Do your stuff
//admin.firestore().collection("test").doc("test").set({...})
return null;
});
The above function will be triggered twice a day - once at midnight and second at 12 noon. There you can fetch your data from any 3rd party API and write it to firestore. The parameter passed in the schedule method is in cron syntax. You can experiment different cron schedules here

Firebase cloud functions dynamic time zones

So in my android app, I am using the real-time database to store information about my users. That information should be updated every Monday at 00:00 o'clock. I am using a cloud function to do this but the problem here is the time zones. Right now I have set the time zone to 'Europe/Sofia' for testing purposes. In the documentation, it is said that the time zone for cloud functions must be from the TZ database. So I figured I could ask the user before registering in my app their preferred time zone and save it in the database. My question is after getting the user's prefered time zone is there a way to only write one cloud function and execute it dynamically for each time zone in the TZ database or do I have to create individual functions for each time zone in the TZ database?
If I correctly understand your question, you could have a scheduled Cloud Function which runs every hour from 00:00 to 23:00 UTC+14:00 on Mondays, and, for every execution (i.e. for every hour within this range), query for the users that should be updated and execute the updates.
I'm not able to enter more into details, based on the info you have provided.
It's not possible to schedule a Cloud Function using a dynamic timezone. You must know the timezone at the time you write the function and declare it statically in your code.
If you want to schedule something dynamically, read through your options in this other question: https://stackoverflow.com/a/42796988/807126
So, you could schedule a repeating function that runs every hour, and check to see if something should be run for a user at the moment in time that it was invoked. Or, you can schedule a single future invocation of a function with a service like Cloud Run, and keep rescheduling it if needed.

Google Cloud Scheduler Run at Set Times Every Minute

I am trying to call an api every minute for ski lift status and check for changes. I am going to store the value of if the lift is open or closed in firebase (Real Time Database) and read to see if value from api is different and only update/ write to that node when it's a different value. Then I can set up a cloud function that will listen for database changes and send push notifications to the list of FCM tokens from that channel. I am not sure if this is the most efficient way, but I was going to set up scheduled functions to call the third party api.
I have been using these docs:
https://firebase.google.com/docs/functions/schedule-functions
I was planning to do something like this:
exports.scheduledFunction = functions.pubsub.schedule('every 5 minutes').onRun((context) => {
CALL MY API IN HERE AND UPDATE DATABASE IF SNAPSHOT BACK IS DIFFERENT
});
I was wondering how would I run only between set times- say 8am-6pm EST. I am struggling to find anything about times to run. Should I just run the function every minute and then pause and resume by checking the time? In which case how does it know to keep checking the time when it is paused?
Firebase scheduled functions use Cloud Scheduler to implement the schedule. It accepts cron style time specifiers to indicate when a job should be run. The full spec for that can be found here. You will have to use ranges of numbers to indicate the valid times and frequency of the schedule. For example, you might use "8-18" in the hour field to limit the hours of execution.

Want to create a scheduled firestore script. Need pointers

Creating an App with Firestore. Need cloud function for document matches that creates new documents/records at periodic intervals.
Looked at firestore cloud functions but still not clear.
My existing knowledge: Create SQL Command bash script as a cron job.
I installed Firebase CLI, setup functions, created example but still unsure what documentation to read nor have good examples to manipulate firestore on a schedule.
Should I use realmDB instead?
App has chat component & data matching creates new records/documents every 6 hours.
Potentially creates upwards of 100,000 records/documents at a time - periodically purged after 14 days.
If you wish to use Firebase Cloud Functions to trigger at periodic intervals (similar to Cron jobs) and run some code, you can use this handy convenience method by Firebase Cloud Functions: https://firebase.google.com/docs/functions/schedule-functions.
exports.scheduledFunctionCrontab = functions.pubsub.schedule('5 11 * * *')
.timeZone('Asia/Kolkata')
.onRun((context) => {
console.log('This will be run every day at 11:00 AM IST!');
return null;
});
You can also setup Google Cloud Pub-Sub triggers manually and use Cloud Scheduler (a Cron job scheduler for GCP) to trigger Pub-Sub trigger.

Schedule jobs in Firebase

I am assuming that someone has reserved 4:30 now and wants to save it to the server and notify the server from the server at 4:30.
I do not want to use the alarm system built into the smartphone.
I also watched Firebase cloud function lectures on YouTube and implemented them. And I've also seen CronJobs, which gets into the URL by alarm on time and executes the function. I have to set the time for the user and give an alarm to each individual.
You may want to look at schedule functions looks like you can do something like:
export scheduledFunction = functions.pubsub.schedule('every 5 minutes')
.onRun((context) => {
console.log('This will be run every 5 minutes!');
});
There is no straight forward way of doing this, but you can go ahead and create a custom scheduler to work around it. A great article with step by step instructions was released by the angularfirebase people at:
https://angularfirebase.com/lessons/scheduled-tasks-and-cron-jobs-with-firebase/

Resources