Build a dynamic task queue with the new cron scheduled Pub/Sub Cloud Functions from Firebase.  https://fireship.io/lessons/cloud-functions-scheduled-time-trigger/

- Cloud Functions Cron Trigger https://firebase.googleblog.com/2019/04/schedule-cloud-functions-firebase-cron.html

Note. This video was recut from an upload yesterday that I decided to take down - some of the editing might seem a little strange.
2024-02-04T06:49:03.770Z
nova-2
2-general-nova
2024-01-09.29447
30089e05-99d1-4376-b32e-c263170674af
810586c4-4bda-4f55-8350-a497f280009c
2b5a047a6397ad3a796584cab555464f9700af7f8faf336935e6463bf18dbad1
67875a7f-c9c4-48a0-aa55-5bdb8a91c34a
deprecated
Yesterday, you may have seen a video about building an industrial scale robocaller.
I decided to take that video down and destroy all the physical copies because even though it's an obvious joke, it's not the right way to be using those tools.
But the good news is that I recut that video, and it keeps the most important part intact, which is building a scheduled task queue with Firebase Cloud Functions.
And make sure to leave a comment on this Video for the t shirt giveaway, even if you left a comment on the original.
And lastly, I just want to take a second to say thank you for supporting the channel.
2019 has already exceeded my Rectations and the video idea list seems to get longer and longer.
Just don't expect any robo color tutorials anytime soon.
Tell him to call me ASAP as possible.
Thanks.
Americans get at least 5,000,000,000 spam robocalls per month, and that number gets bigger and bigger every year.
Personally, I get at least 10 of those calls per day, and I finally just decided if you can't beat them, join them.
In today's video, we're going to not build a robo column using and a brand new Cloud Function type from Firebase.
But more importantly, we're going to build a task runner that allows us to schedule any back end code to run at any If you're new here, like and subscribe, and you can find the full source code on Fireship IO.
And leave a comment below for a chance to win this one of a kind t shirt next week.
So Firebase released a new function type a couple days ago.
It's a PubSub function, which allows you to pass messages in between Google services that is also integrated with Google Cloud Scheduler.
This means you can run any back end code at a specific point in time using a crontab schedule.
This is great if you know exactly when you wanna schedule a job in advance, But I want to push things a step further by integrating Firestore to create a dynamic task runner that allows you to schedule a job at any point in time.
That allows you or your users to schedule anything Dynamically, such as notifications, reminders, or as we'll see soon Definitely not robo callers.
Make sure you have the latest version of Firebase Tools installed version 6.7 or version 2.3 of the Firebase functions module.
From there, we can initialize a new project by running Firebase init functions.
I'll be using TypeScript, and you'll see why it's so valuable for a project like this in a few minutes.
Let's start by taking a look at a basic scheduled pubsub function.
In the index.
Ts, I have a reference to the admin SDK as well as Firestore, which we'll be using later.
To create a scheduled function, we'll call functions.pubsub.
Scheduled.
The scheduled method takes a crontab schedule as its argument, which itself is just a string with 5 slots that represent the minute, hour, day, month, and weekday of the schedule.
In my code here, I have the minutes set to 30 and the hour to 5, so this will tick at 5:30 AM every day.
But I wouldn't recommend trying to memorize how Cron schedules work because there's this app called Chrontap Guru that makes it easy to edit and customize Cron schedules.
From there, we just call on run.
That gives us access to a callback function which can execute background code on the schedule.
That's easy enough, but our schedule is static, so what if we want to change the Schedule or allow the user to schedule something dynamically.
In this demo, we want to build a robocaller that can scale up to millions of phone calls per day and schedule those calls at different times throughout the day.
For that, we're going to build a dynamic task runner and we'll start by modeling the data with Firestore.
We'll create a task collection And each document will represent a job that we want to run-in the background at a specific point in time.
The first field you'll see here is worker, which is just a string that represents a JavaScript function that lives somewhere in our back end code.
The worker handles all of the business logic, And the Firestore document is really just a messenger to pass data to the back end.
The next field is status.
This will just tell us whether or not a task has been completed or whether or not scheduled or maybe it errored out.
The next field is perform at, which is a time stamp that tells us when to execute this task.
You'll wanna make sure that this is a Firestore Store time stamp to ensure it's consistent across all of your clients.
Then the 4th and final field is options, which is just a map that allows us to pass any serialized data into the back end function.
Chen.
So what we're going for here is a generic system that allows us to name a function and then pass some data to that function and have it run securely in the back again on a specific schedule that can be user defined if you create this document in the front end.
That's how we get data to the back end.
Now we need to execute it by defining a task runner.
This is simply a scheduled function that runs every 60 seconds and checks to see if we have any jobs that need to be executed.
This function will be invoked about 45,000 times per month, which is well within the free tier on Firebase if you're worried about cost.
And you can even use this to optimize cost because you can run multiple jobs within a single function invocation.
I'm I'm gonna go ahead and create a function called Task Runner, and I'm going to increase the memory to 2 gigabytes.
That part's completely optional, but if you're running a lot of tasks, you might want to just max out the memory.
And then we'll call pubsubschedule, and for the schedule, we'll pass all stars or wildcards.
This will have the function tick every 1 minute, And that's actually the max level of granularity that you can achieve with a crontap schedule.
It's likely that we want to run a lot of different jobs concurrently.
So we'll do this inside of an async function, and then we'll want to get the current time as represented by a Firestore time stamp.
We can use this to query Firestore for every job that has a perform at timestamp in the past.
Those are the jobs that we want to run right now.
And then we'll also make sure that each task is scheduled because we don't want to run a job that's already been completed.
This will make it a composite query, so keep in mind you'll need an index in Firestore to run this query.
The next thing we'll do is read this collection by calling await query get, and then we're going to make sure that each job is a promise.
So I'm creating an empty array here that will be an array of promises that we Can execute concurrently.
From there, I'll loop over every document in the collection, and from each document, I want the worker function name as well as any options that we need to pass into that function.
We haven't defined the worker functions yet, but we'll do that in the next step.
It's simply going to be an object that has a series of functions on it, so we can call those functions based on the object's Property name.
Now because we're going to force each worker function to return a promise, we can run them all concurrently, and we can also handle the success and error cases in a way that's generic So we can handle it the same way for every job that's enqueued no matter what its business logic is doing.
In this case, we'll just go ahead and update the underlying document to a status of complete, or if it's an Error will update it to a status of error.
And lastly, we'll go ahead and push it to the jobs array.
And the final thing we need to do from our task runner is just return promise dot all with the jobs array.
So that's all it takes to create a basic task runner with this new PubSub function type and Firestore.
Now it's time to define the business logic for the task runner.
The logic will be kept in this workers object, and I'm going to create an interface for this object because it has a specific signature that it needs to follow.
The keys can be any value.
That's the name of the function.
And then the function itself has an options object, which we can use to pass in any dynamic data to the function at runtime.
And that corresponds to the options map on the Firestore document.
And lastly, we want to enforce that each worker function returns a promise.
Now we'll go ahead and define the worker's object, and we'll give it a key of hello world, which is a function that just returns a right to the Firestore database.
Let's go ahead and deploy our function and make sure the task runner is working.
We'll go into Firestore to the task collection, set the worker to hello world, Then set the status to scheduled and the time stamp to sometime in the past.
After that, we just need to wait about a minute and then we should see the status flip to complete.
And then we should also see this hello, world document in the logs collection.
In the original video, this is the point where we built the robocaller, but I'm just gonna go ahead and wrap things up here.
The important takeaway is that you now have a system that can schedule any back end code dynamically.
Some good use cases might be allowing users to schedule push Vacations, reminders, or transactional email, but Definitely not robo callers.
If this video helped you, please like and subscribe, and consider becoming a pro member at FireShip IO to get access to even more content.
Thanks for watching, and I will talk to you soon.

Speaker 0: Yesterday, you may have seen a video about building an industrial scale robocaller. I decided to take that video down and destroy all the physical copies because even though it's an obvious joke, it's not the right way to be using those tools. But the good news is that I recut that video, and it keeps the most important part intact, which is building a scheduled task queue with Firebase Cloud Functions. And make sure to leave a comment on this Video for the t shirt giveaway, even if you left a comment on the original. And lastly, I just want to take a second to say thank you for supporting the channel.

2019 has already exceeded my Rectations and the video idea list seems to get longer and longer. Just don't expect any robo color tutorials anytime soon. Tell him to call me ASAP as possible. Thanks. Americans get at least 5,000,000,000 spam robocalls per month, and that number gets bigger and bigger every year.

Personally, I get at least 10 of those calls per day, and I finally just decided if you can't beat them, join them. In today's video, we're going to not build a robo column using and a brand new Cloud Function type from Firebase. But more importantly, we're going to build a task runner that allows us to schedule any back end code to run at any If you're new here, like and subscribe, and you can find the full source code on Fireship IO. And leave a comment below for a chance to win this one of a kind t shirt next week. So Firebase released a new function type a couple days ago.

It's a PubSub function, which allows you to pass messages in between Google services that is also integrated with Google Cloud Scheduler. This means you can run any back end code at a specific point in time using a crontab schedule. This is great if you know exactly when you wanna schedule a job in advance, But I want to push things a step further by integrating Firestore to create a dynamic task runner that allows you to schedule a job at any point in time. That allows you or your users to schedule anything Dynamically, such as notifications, reminders, or as we'll see soon Definitely not robo callers. Make sure you have the latest version of Firebase Tools installed version 6.7 or version 2.3 of the Firebase functions module.

From there, we can initialize a new project by running Firebase init functions. I'll be using TypeScript, and you'll see why it's so valuable for a project like this in a few minutes. Let's start by taking a look at a basic scheduled pubsub function. In the index. Ts, I have a reference to the admin SDK as well as Firestore, which we'll be using later.

To create a scheduled function, we'll call functions.pubsub. Scheduled. The scheduled method takes a crontab schedule as its argument, which itself is just a string with 5 slots that represent the minute, hour, day, month, and weekday of the schedule. In my code here, I have the minutes set to 30 and the hour to 5, so this will tick at 5:30 AM every day. But I wouldn't recommend trying to memorize how Cron schedules work because there's this app called Chrontap Guru that makes it easy to edit and customize Cron schedules.

From there, we just call on run. That gives us access to a callback function which can execute background code on the schedule. That's easy enough, but our schedule is static, so what if we want to change the Schedule or allow the user to schedule something dynamically. In this demo, we want to build a robocaller that can scale up to millions of phone calls per day and schedule those calls at different times throughout the day. For that, we're going to build a dynamic task runner and we'll start by modeling the data with Firestore.

We'll create a task collection And each document will represent a job that we want to run-in the background at a specific point in time. The first field you'll see here is worker, which is just a string that represents a JavaScript function that lives somewhere in our back end code. The worker handles all of the business logic, And the Firestore document is really just a messenger to pass data to the back end. The next field is status. This will just tell us whether or not a task has been completed or whether or not scheduled or maybe it errored out.

The next field is perform at, which is a time stamp that tells us when to execute this task. You'll wanna make sure that this is a Firestore Store time stamp to ensure it's consistent across all of your clients. Then the 4th and final field is options, which is just a map that allows us to pass any serialized data into the back end function. Chen. So what we're going for here is a generic system that allows us to name a function and then pass some data to that function and have it run securely in the back again on a specific schedule that can be user defined if you create this document in the front end.

That's how we get data to the back end. Now we need to execute it by defining a task runner. This is simply a scheduled function that runs every 60 seconds and checks to see if we have any jobs that need to be executed. This function will be invoked about 45,000 times per month, which is well within the free tier on Firebase if you're worried about cost. And you can even use this to optimize cost because you can run multiple jobs within a single function invocation.

I'm I'm gonna go ahead and create a function called Task Runner, and I'm going to increase the memory to 2 gigabytes. That part's completely optional, but if you're running a lot of tasks, you might want to just max out the memory. And then we'll call pubsubschedule, and for the schedule, we'll pass all stars or wildcards. This will have the function tick every 1 minute, And that's actually the max level of granularity that you can achieve with a crontap schedule. It's likely that we want to run a lot of different jobs concurrently.

So we'll do this inside of an async function, and then we'll want to get the current time as represented by a Firestore time stamp. We can use this to query Firestore for every job that has a perform at timestamp in the past. Those are the jobs that we want to run right now. And then we'll also make sure that each task is scheduled because we don't want to run a job that's already been completed. This will make it a composite query, so keep in mind you'll need an index in Firestore to run this query.

The next thing we'll do is read this collection by calling await query get, and then we're going to make sure that each job is a promise. So I'm creating an empty array here that will be an array of promises that we Can execute concurrently. From there, I'll loop over every document in the collection, and from each document, I want the worker function name as well as any options that we need to pass into that function. We haven't defined the worker functions yet, but we'll do that in the next step. It's simply going to be an object that has a series of functions on it, so we can call those functions based on the object's Property name.

Now because we're going to force each worker function to return a promise, we can run them all concurrently, and we can also handle the success and error cases in a way that's generic So we can handle it the same way for every job that's enqueued no matter what its business logic is doing. In this case, we'll just go ahead and update the underlying document to a status of complete, or if it's an Error will update it to a status of error. And lastly, we'll go ahead and push it to the jobs array. And the final thing we need to do from our task runner is just return promise dot all with the jobs array. So that's all it takes to create a basic task runner with this new PubSub function type and Firestore.

Now it's time to define the business logic for the task runner. The logic will be kept in this workers object, and I'm going to create an interface for this object because it has a specific signature that it needs to follow. The keys can be any value. That's the name of the function. And then the function itself has an options object, which we can use to pass in any dynamic data to the function at runtime.

And that corresponds to the options map on the Firestore document. And lastly, we want to enforce that each worker function returns a promise. Now we'll go ahead and define the worker's object, and we'll give it a key of hello world, which is a function that just returns a right to the Firestore database. Let's go ahead and deploy our function and make sure the task runner is working. We'll go into Firestore to the task collection, set the worker to hello world, Then set the status to scheduled and the time stamp to sometime in the past.

After that, we just need to wait about a minute and then we should see the status flip to complete. And then we should also see this hello, world document in the logs collection. In the original video, this is the point where we built the robocaller, but I'm just gonna go ahead and wrap things up here. The important takeaway is that you now have a system that can schedule any back end code dynamically. Some good use cases might be allowing users to schedule push Vacations, reminders, or transactional email, but Definitely not robo callers.

If this video helped you, please like and subscribe, and consider becoming a pro member at FireShip IO to get access to even more content. Thanks for watching, and I will talk to you soon.
Yesterday, you may have seen a video about building an industrial scale robocaller. I decided to take that video down and destroy all the physical copies because even though it's an obvious joke, it's not the right way to be using those tools. But the good news is that I recut that video, and it keeps the most important part intact, which is building a scheduled task queue with Firebase Cloud Functions. And make sure to leave a comment on this Video for the t shirt giveaway, even if you left a comment on the original. And lastly, I just want to take a second to say thank you for supporting the channel. 2019 has already exceeded my Rectations and the video idea list seems to get longer and longer.
video gaming
multimedia
streaming
youtube
social media
Just don't expect any robo color tutorials anytime soon.
Tell him to call me ASAP as possible. Thanks. Americans get at least 5,000,000,000 spam robocalls per month, and that number gets bigger and bigger every year. Personally, I get at least 10 of those calls per day, and I finally just decided if you can't beat them, join them.
phones
In today's video, we're going to not build a robo column using and a brand new Cloud Function type from Firebase. But more importantly, we're going to build a task runner that allows us to schedule any back end code to run at any If you're new here, like and subscribe, and you can find the full source code on Fireship IO. And leave a comment below for a chance to win this one of a kind t shirt next week. So Firebase released a new function type a couple days ago. It's a PubSub function, which allows you to pass messages in between Google services that is also integrated with Google Cloud Scheduler. This means you can run any back end code at a specific point in time using a crontab schedule. This is great if you know exactly when you wanna schedule a job in advance, But I want to push things a step further by integrating Firestore to create a dynamic task runner that allows you to schedule a job at any point in time. That allows you or your users to schedule anything Dynamically, such as notifications, reminders, or as we'll see soon Definitely not robo callers. Make sure you have the latest version of Firebase Tools installed version 6.7 or version 2.3 of the Firebase functions module. From there, we can initialize a new project by running Firebase init functions. I'll be using TypeScript, and you'll see why it's so valuable for a project like this in a few minutes. Let's start by taking a look at a basic scheduled pubsub function. In the index. Ts, I have a reference to the admin SDK as well as Firestore, which we'll be using later. To create a scheduled function, we'll call functions.pubsub. Scheduled. The scheduled method takes a crontab schedule as its argument, which itself is just a string with 5 slots that represent the minute, hour, day, month, and weekday of the schedule. In my code here, I have the minutes set to 30 and the hour to 5, so this will tick at 5:30 AM every day. But I wouldn't recommend trying to memorize how Cron schedules work because there's this app called Chrontap Guru that makes it easy to edit and customize Cron schedules. From there, we just call on run. That gives us access to a callback function which can execute background code on the schedule. That's easy enough, but our schedule is static, so what if we want to change the Schedule or allow the user to schedule something dynamically.
In this demo, we want to build a robocaller that can scale up to millions of phone calls per day and schedule those calls at different times throughout the day. For that, we're going to build a dynamic task runner and we'll start by modeling the data with Firestore. We'll create a task collection And each document will represent a job that we want to run-in the background at a specific point in time.
phones
The first field you'll see here is worker, which is just a string that represents a JavaScript function that lives somewhere in our back end code. The worker handles all of the business logic, And the Firestore document is really just a messenger to pass data to the back end. The next field is status. This will just tell us whether or not a task has been completed or whether or not scheduled or maybe it errored out. The next field is perform at, which is a time stamp that tells us when to execute this task.
You'll wanna make sure that this is a Firestore Store time stamp to ensure it's consistent across all of your clients. Then the 4th and final field is options, which is just a map that allows us to pass any serialized data into the back end function. Chen. So what we're going for here is a generic system that allows us to name a function and then pass some data to that function and have it run securely in the back again on a specific schedule that can be user defined if you create this document in the front end.
programming
systems
databases
documentation
software
That's how we get data to the back end. Now we need to execute it by defining a task runner. This is simply a scheduled function that runs every 60 seconds and checks to see if we have any jobs that need to be executed. This function will be invoked about 45,000 times per month, which is well within the free tier on Firebase if you're worried about cost. And you can even use this to optimize cost because you can run multiple jobs within a single function invocation. I'm I'm gonna go ahead and create a function called Task Runner, and I'm going to increase the memory to 2 gigabytes. That part's completely optional, but if you're running a lot of tasks, you might want to just max out the memory. And then we'll call pubsubschedule, and for the schedule, we'll pass all stars or wildcards. This will have the function tick every 1 minute, And that's actually the max level of granularity that you can achieve with a crontap schedule. It's likely that we want to run a lot of different jobs concurrently. So we'll do this inside of an async function, and then we'll want to get the current time as represented by a Firestore time stamp. We can use this to query Firestore for every job that has a perform at timestamp in the past. Those are the jobs that we want to run right now. And then we'll also make sure that each task is scheduled because we don't want to run a job that's already been completed. This will make it a composite query, so keep in mind you'll need an index in Firestore to run this query. The next thing we'll do is read this collection by calling await query get, and then we're going to make sure that each job is a promise. So I'm creating an empty array here that will be an array of promises that we Can execute concurrently. From there, I'll loop over every document in the collection, and from each document, I want the worker function name as well as any options that we need to pass into that function.
We haven't defined the worker functions yet, but we'll do that in the next step. It's simply going to be an object that has a series of functions on it, so we can call those functions based on the object's Property name. Now because we're going to force each worker function to return a promise, we can run them all concurrently, and we can also handle the success and error cases in a way that's generic So we can handle it the same way for every job that's enqueued no matter what its business logic is doing.
operations
logic
In this case, we'll just go ahead and update the underlying document to a status of complete, or if it's an Error will update it to a status of error. And lastly, we'll go ahead and push it to the jobs array. And the final thing we need to do from our task runner is just return promise dot all with the jobs array. So that's all it takes to create a basic task runner with this new PubSub function type and Firestore. Now it's time to define the business logic for the task runner.
The logic will be kept in this workers object, and I'm going to create an interface for this object because it has a specific signature that it needs to follow. The keys can be any value. That's the name of the function. And then the function itself has an options object, which we can use to pass in any dynamic data to the function at runtime.
logic
And that corresponds to the options map on the Firestore document. And lastly, we want to enforce that each worker function returns a promise. Now we'll go ahead and define the worker's object, and we'll give it a key of hello world, which is a function that just returns a right to the Firestore database. Let's go ahead and deploy our function and make sure the task runner is working. We'll go into Firestore to the task collection, set the worker to hello world, Then set the status to scheduled and the time stamp to sometime in the past. After that, we just need to wait about a minute and then we should see the status flip to complete. And then we should also see this hello, world document in the logs collection. In the original video, this is the point where we built the robocaller, but I'm just gonna go ahead and wrap things up here. The important takeaway is that you now have a system that can schedule any back end code dynamically. Some good use cases might be allowing users to schedule push Vacations, reminders, or transactional email, but Definitely not robo callers. If this video helped you, please like and subscribe, and consider becoming a pro member at FireShip IO to get access to even more content. Thanks for watching, and I will talk to you soon.
Yesterday, you may have seen a video about building an industrial scale robocaller. I decided to take that video down and destroy all the physical copies because even though it's an obvious joke, it's not the right way to be using those tools. But the good news is that I recut that video, and it keeps the most important part intact, which is building a scheduled task queue with Firebase Cloud Functions. And make sure to leave a comment on this Video for the t shirt giveaway, even if you left a comment on the original. And lastly, I just want to take a second to say thank you for supporting the channel. 2019 has already exceeded my Rectations and the video idea list seems to get longer and longer. Just don't expect any robo color tutorials anytime soon. Tell him to call me ASAP as possible. Thanks. Americans get at least 5,000,000,000 spam robocalls per month, and that number gets bigger and bigger every year. Personally, I get at least 10 of those calls per day, and I finally just decided if you can't beat them, join them. In today's video, we're going to not build a robo column using and a brand new Cloud Function type from Firebase. But more importantly, we're going to build a task runner that allows us to schedule any back end code to run at any If you're new here, like and subscribe, and you can find the full source code on Fireship IO. And leave a comment below for a chance to win this one of a kind t shirt next week. So Firebase released a new function type a couple days ago. It's a PubSub function, which allows you to pass messages in between Google services that is also integrated with Google Cloud Scheduler. This means you can run any back end code at a specific point in time using a crontab schedule. This is great if you know exactly when you wanna schedule a job in advance, But I want to push things a step further by integrating Firestore to create a dynamic task runner that allows you to schedule a job at any point in time. That allows you or your users to schedule anything Dynamically, such as notifications, reminders, or as we'll see soon Definitely not robo callers. Make sure you have the latest version of Firebase Tools installed version 6.7 or version 2.3 of the Firebase functions module. From there, we can initialize a new project by running Firebase init functions. I'll be using TypeScript, and you'll see why it's so valuable for a project like this in a few minutes. Let's start by taking a look at a basic scheduled pubsub function. In the index. Ts, I have a reference to the admin SDK as well as Firestore, which we'll be using later. To create a scheduled function, we'll call functions.pubsub. Scheduled. The scheduled method takes a crontab schedule as its argument, which itself is just a string with 5 slots that represent the minute, hour, day, month, and weekday of the schedule. In my code here, I have the minutes set to 30 and the hour to 5, so this will tick at 5:30 AM every day. But I wouldn't recommend trying to memorize how Cron schedules work because there's this app called Chrontap Guru that makes it easy to edit and customize Cron schedules. From there, we just call on run. That gives us access to a callback function which can execute background code on the schedule. That's easy enough, but our schedule is static, so what if we want to change the Schedule or allow the user to schedule something dynamically. In this demo, we want to build a robocaller that can scale up to millions of phone calls per day and schedule those calls at different times throughout the day. For that, we're going to build a dynamic task runner and we'll start by modeling the data with Firestore. We'll create a task collection And each document will represent a job that we want to run-in the background at a specific point in time. The first field you'll see here is worker, which is just a string that represents a JavaScript function that lives somewhere in our back end code. The worker handles all of the business logic, And the Firestore document is really just a messenger to pass data to the back end. The next field is status. This will just tell us whether or not a task has been completed or whether or not scheduled or maybe it errored out. The next field is perform at, which is a time stamp that tells us when to execute this task. You'll wanna make sure that this is a Firestore Store time stamp to ensure it's consistent across all of your clients. Then the 4th and final field is options, which is just a map that allows us to pass any serialized data into the back end function. Chen. So what we're going for here is a generic system that allows us to name a function and then pass some data to that function and have it run securely in the back again on a specific schedule that can be user defined if you create this document in the front end. That's how we get data to the back end. Now we need to execute it by defining a task runner. This is simply a scheduled function that runs every 60 seconds and checks to see if we have any jobs that need to be executed. This function will be invoked about 45,000 times per month, which is well within the free tier on Firebase if you're worried about cost. And you can even use this to optimize cost because you can run multiple jobs within a single function invocation. I'm I'm gonna go ahead and create a function called Task Runner, and I'm going to increase the memory to 2 gigabytes. That part's completely optional, but if you're running a lot of tasks, you might want to just max out the memory. And then we'll call pubsubschedule, and for the schedule, we'll pass all stars or wildcards. This will have the function tick every 1 minute, And that's actually the max level of granularity that you can achieve with a crontap schedule. It's likely that we want to run a lot of different jobs concurrently. So we'll do this inside of an async function, and then we'll want to get the current time as represented by a Firestore time stamp. We can use this to query Firestore for every job that has a perform at timestamp in the past. Those are the jobs that we want to run right now. And then we'll also make sure that each task is scheduled because we don't want to run a job that's already been completed. This will make it a composite query, so keep in mind you'll need an index in Firestore to run this query. The next thing we'll do is read this collection by calling await query get, and then we're going to make sure that each job is a promise. So I'm creating an empty array here that will be an array of promises that we Can execute concurrently. From there, I'll loop over every document in the collection, and from each document, I want the worker function name as well as any options that we need to pass into that function. We haven't defined the worker functions yet, but we'll do that in the next step. It's simply going to be an object that has a series of functions on it, so we can call those functions based on the object's Property name. Now because we're going to force each worker function to return a promise, we can run them all concurrently, and we can also handle the success and error cases in a way that's generic So we can handle it the same way for every job that's enqueued no matter what its business logic is doing. In this case, we'll just go ahead and update the underlying document to a status of complete, or if it's an Error will update it to a status of error. And lastly, we'll go ahead and push it to the jobs array. And the final thing we need to do from our task runner is just return promise dot all with the jobs array. So that's all it takes to create a basic task runner with this new PubSub function type and Firestore. Now it's time to define the business logic for the task runner. The logic will be kept in this workers object, and I'm going to create an interface for this object because it has a specific signature that it needs to follow. The keys can be any value. That's the name of the function. And then the function itself has an options object, which we can use to pass in any dynamic data to the function at runtime. And that corresponds to the options map on the Firestore document. And lastly, we want to enforce that each worker function returns a promise. Now we'll go ahead and define the worker's object, and we'll give it a key of hello world, which is a function that just returns a right to the Firestore database. Let's go ahead and deploy our function and make sure the task runner is working. We'll go into Firestore to the task collection, set the worker to hello world, Then set the status to scheduled and the time stamp to sometime in the past. After that, we just need to wait about a minute and then we should see the status flip to complete. And then we should also see this hello, world document in the logs collection. In the original video, this is the point where we built the robocaller, but I'm just gonna go ahead and wrap things up here. The important takeaway is that you now have a system that can schedule any back end code dynamically. Some good use cases might be allowing users to schedule push Vacations, reminders, or transactional email, but Definitely not robo callers. If this video helped you, please like and subscribe, and consider becoming a pro member at FireShip IO to get access to even more content. Thanks for watching, and I will talk to you soon.
Yesterday,
yesterday
you
you
may
may
have
have
seen
seen
a
a
video
video
about
about
building
building
an
an
industrial
industrial
scale
scale
robocaller.
robocaller
I
i
decided
decided
to
to
take
take
that
that
video
video
down
down
and
and
destroy
destroy
all
all
the
the
physical
physical
copies
copies
because
because
even
even
though
though
it's
it's
an
an
obvious
obvious
joke,
joke
it's
it's
not
not
the
the
right
right
way
way
to
to
be
be
using
using
those
those
tools.
tools
But
but
the
the
good
good
news
news
is
is
that
that
I
i
recut
recut
that
that
video,
video
and
and
it
it
keeps
keeps
the
the
most
most
important
important
part
part
intact,
intact
which
which
is
is
building
building
a
a
scheduled
scheduled
task
task
queue
queue
with
with
Firebase
firebase
Cloud
cloud
Functions.
functions
And
and
make
make
sure
sure
to
to
leave
leave
a
a
comment
comment
on
on
this
this
Video
video
for
for
the
the
t
t
shirt
shirt
giveaway,
giveaway
even
even
if
if
you
you
left
left
a
a
comment
comment
on
on
the
the
original.
original
And
and
lastly,
lastly
I
i
just
just
want
want
to
to
take
take
a
a
second
second
to
to
say
say
thank
thank
you
you
for
for
supporting
supporting
the
the
channel.
channel
2019
2019
has
has
already
already
exceeded
exceeded
my
my
Rectations
rectations
and
and
the
the
video
video
idea
idea
list
list
seems
seems
to
to
get
get
longer
longer
and
and
longer.
longer
Just
just
don't
don't
expect
expect
any
any
robo
robo
color
color
tutorials
tutorials
anytime
anytime
soon.
soon
Tell
tell
him
him
to
to
call
call
me
me
ASAP
asap
as
as
possible.
possible
Thanks.
thanks
Americans
americans
get
get
at
at
least
least
5,000,000,000
5,000,000,000
spam
spam
robocalls
robocalls
per
per
month,
month
and
and
that
that
number
number
gets
gets
bigger
bigger
and
and
bigger
bigger
every
every
year.
year
Personally,
personally
I
i
get
get
at
at
least
least
10
10
of
of
those
those
calls
calls
per
per
day,
day
and
and
I
i
finally
finally
just
just
decided
decided
if
if
you
you
can't
can't
beat
beat
them,
them
join
join
them.
them
In
in
today's
today's
video,
video
we're
we're
going
going
to
to
not
not
build
build
a
a
robo
robo
column
column
using
using
and
and
a
a
brand
brand
new
new
Cloud
cloud
Function
function
type
type
from
from
Firebase.
firebase
But
but
more
more
importantly,
importantly
we're
we're
going
going
to
to
build
build
a
a
task
task
runner
runner
that
that
allows
allows
us
us
to
to
schedule
schedule
any
any
back
back
end
end
code
code
to
to
run
run
at
at
any
any
If
if
you're
you're
new
new
here,
here
like
like
and
and
subscribe,
subscribe
and
and
you
you
can
can
find
find
the
the
full
full
source
source
code
code
on
on
Fireship
fireship
IO.
io
And
and
leave
leave
a
a
comment
comment
below
below
for
for
a
a
chance
chance
to
to
win
win
this
this
one
one
of
of
a
a
kind
kind
t
t
shirt
shirt
next
next
week.
week
So
so
Firebase
firebase
released
released
a
a
new
new
function
function
type
type
a
a
couple
couple
days
days
ago.
ago
It's
it's
a
a
PubSub
pubsub
function,
function
which
which
allows
allows
you
you
to
to
pass
pass
messages
messages
in
in
between
between
Google
google
services
services
that
that
is
is
also
also
integrated
integrated
with
with
Google
google
Cloud
cloud
Scheduler.
scheduler
This
this
means
means
you
you
can
can
run
run
any
any
back
back
end
end
code
code
at
at
a
a
specific
specific
point
point
in
in
time
time
using
using
a
a
crontab
crontab
schedule.
schedule
This
this
is
is
great
great
if
if
you
you
know
know
exactly
exactly
when
when
you
you
wanna
wanna
schedule
schedule
a
a
job
job
in
in
advance,
advance
But
but
I
i
want
want
to
to
push
push
things
things
a
a
step
step
further
further
by
by
integrating
integrating
Firestore
firestore
to
to
create
create
a
a
dynamic
dynamic
task
task
runner
runner
that
that
allows
allows
you
you
to
to
schedule
schedule
a
a
job
job
at
at
any
any
point
point
in
in
time.
time
That
that
allows
allows
you
you
or
or
your
your
users
users
to
to
schedule
schedule
anything
anything
Dynamically,
dynamically
such
such
as
as
notifications,
notifications
reminders,
reminders
or
or
as
as
we'll
we'll
see
see
soon
soon
Definitely
definitely
not
not
robo
robo
callers.
callers
Make
make
sure
sure
you
you
have
have
the
the
latest
latest
version
version
of
of
Firebase
firebase
Tools
tools
installed
installed
version
version
6.7
6.7
or
or
version
version
2.3
2.3
of
of
the
the
Firebase
firebase
functions
functions
module.
module
From
from
there,
there
we
we
can
can
initialize
initialize
a
a
new
new
project
project
by
by
running
running
Firebase
firebase
init
init
functions.
functions
I'll
i'll
be
be
using
using
TypeScript,
typescript
and
and
you'll
you'll
see
see
why
why
it's
it's
so
so
valuable
valuable
for
for
a
a
project
project
like
like
this
this
in
in
a
a
few
few
minutes.
minutes
Let's
let's
start
start
by
by
taking
taking
a
a
look
look
at
at
a
a
basic
basic
scheduled
scheduled
pubsub
pubsub
function.
function
In
in
the
the
index.
index
Ts,
ts
I
i
have
have
a
a
reference
reference
to
to
the
the
admin
admin
SDK
sdk
as
as
well
well
as
as
Firestore,
firestore
which
which
we'll
we'll
be
be
using
using
later.
later
To
to
create
create
a
a
scheduled
scheduled
function,
function
we'll
we'll
call
call
functions.pubsub.
functions.pubsub
Scheduled.
scheduled
The
the
scheduled
scheduled
method
method
takes
takes
a
a
crontab
crontab
schedule
schedule
as
as
its
its
argument,
argument
which
which
itself
itself
is
is
just
just
a
a
string
string
with
with
5
5
slots
slots
that
that
represent
represent
the
the
minute,
minute
hour,
hour
day,
day
month,
month
and
and
weekday
weekday
of
of
the
the
schedule.
schedule
In
in
my
my
code
code
here,
here
I
i
have
have
the
the
minutes
minutes
set
set
to
to
30
30
and
and
the
the
hour
hour
to
to
5,
5
so
so
this
this
will
will
tick
tick
at
at
5:30
5:30
AM
am
every
every
day.
day
But
but
I
i
wouldn't
wouldn't
recommend
recommend
trying
trying
to
to
memorize
memorize
how
how
Cron
cron
schedules
schedules
work
work
because
because
there's
there's
this
this
app
app
called
called
Chrontap
chrontap
Guru
guru
that
that
makes
makes
it
it
easy
easy
to
to
edit
edit
and
and
customize
customize
Cron
cron
schedules.
schedules
From
from
there,
there
we
we
just
just
call
call
on
on
run.
run
That
that
gives
gives
us
us
access
access
to
to
a
a
callback
callback
function
function
which
which
can
can
execute
execute
background
background
code
code
on
on
the
the
schedule.
schedule
That's
that's
easy
easy
enough,
enough
but
but
our
our
schedule
schedule
is
is
static,
static
so
so
what
what
if
if
we
we
want
want
to
to
change
change
the
the
Schedule
schedule
or
or
allow
allow
the
the
user
user
to
to
schedule
schedule
something
something
dynamically.
dynamically
In
in
this
this
demo,
demo
we
we
want
want
to
to
build
build
a
a
robocaller
robocaller
that
that
can
can
scale
scale
up
up
to
to
millions
millions
of
of
phone
phone
calls
calls
per
per
day
day
and
and
schedule
schedule
those
those
calls
calls
at
at
different
different
times
times
throughout
throughout
the
the
day.
day
For
for
that,
that
we're
we're
going
going
to
to
build
build
a
a
dynamic
dynamic
task
task
runner
runner
and
and
we'll
we'll
start
start
by
by
modeling
modeling
the
the
data
data
with
with
Firestore.
firestore
We'll
we'll
create
create
a
a
task
task
collection
collection
And
and
each
each
document
document
will
will
represent
represent
a
a
job
job
that
that
we
we
want
want
to
to
run-in
run-in
the
the
background
background
at
at
a
a
specific
specific
point
point
in
in
time.
time
The
the
first
first
field
field
you'll
you'll
see
see
here
here
is
is
worker,
worker
which
which
is
is
just
just
a
a
string
string
that
that
represents
represents
a
a
JavaScript
javascript
function
function
that
that
lives
lives
somewhere
somewhere
in
in
our
our
back
back
end
end
code.
code
The
the
worker
worker
handles
handles
all
all
of
of
the
the
business
business
logic,
logic
And
and
the
the
Firestore
firestore
document
document
is
is
really
really
just
just
a
a
messenger
messenger
to
to
pass
pass
data
data
to
to
the
the
back
back
end.
end
The
the
next
next
field
field
is
is
status.
status
This
this
will
will
just
just
tell
tell
us
us
whether
whether
or
or
not
not
a
a
task
task
has
has
been
been
completed
completed
or
or
whether
whether
or
or
not
not
scheduled
scheduled
or
or
maybe
maybe
it
it
errored
errored
out.
out
The
the
next
next
field
field
is
is
perform
perform
at,
at
which
which
is
is
a
a
time
time
stamp
stamp
that
that
tells
tells
us
us
when
when
to
to
execute
execute
this
this
task.
task
You'll
you'll
wanna
wanna
make
make
sure
sure
that
that
this
this
is
is
a
a
Firestore
firestore
Store
store
time
time
stamp
stamp
to
to
ensure
ensure
it's
it's
consistent
consistent
across
across
all
all
of
of
your
your
clients.
clients
Then
then
the
the
4th
4th
and
and
final
final
field
field
is
is
options,
options
which
which
is
is
just
just
a
a
map
map
that
that
allows
allows
us
us
to
to
pass
pass
any
any
serialized
serialized
data
data
into
into
the
the
back
back
end
end
function.
function
Chen.
chen
So
so
what
what
we're
we're
going
going
for
for
here
here
is
is
a
a
generic
generic
system
system
that
that
allows
allows
us
us
to
to
name
name
a
a
function
function
and
and
then
then
pass
pass
some
some
data
data
to
to
that
that
function
function
and
and
have
have
it
it
run
run
securely
securely
in
in
the
the
back
back
again
again
on
on
a
a
specific
specific
schedule
schedule
that
that
can
can
be
be
user
user
defined
defined
if
if
you
you
create
create
this
this
document
document
in
in
the
the
front
front
end.
end
That's
that's
how
how
we
we
get
get
data
data
to
to
the
the
back
back
end.
end
Now
now
we
we
need
need
to
to
execute
execute
it
it
by
by
defining
defining
a
a
task
task
runner.
runner
This
this
is
is
simply
simply
a
a
scheduled
scheduled
function
function
that
that
runs
runs
every
every
60
60
seconds
seconds
and
and
checks
checks
to
to
see
see
if
if
we
we
have
have
any
any
jobs
jobs
that
that
need
need
to
to
be
be
executed.
executed
This
this
function
function
will
will
be
be
invoked
invoked
about
about
45,000
45,000
times
times
per
per
month,
month
which
which
is
is
well
well
within
within
the
the
free
free
tier
tier
on
on
Firebase
firebase
if
if
you're
you're
worried
worried
about
about
cost.
cost
And
and
you
you
can
can
even
even
use
use
this
this
to
to
optimize
optimize
cost
cost
because
because
you
you
can
can
run
run
multiple
multiple
jobs
jobs
within
within
a
a
single
single
function
function
invocation.
invocation
I'm
i'm
I'm
i'm
gonna
gonna
go
go
ahead
ahead
and
and
create
create
a
a
function
function
called
called
Task
task
Runner,
runner
and
and
I'm
i'm
going
going
to
to
increase
increase
the
the
memory
memory
to
to
2
2
gigabytes.
gigabytes
That
that
part's
part's
completely
completely
optional,
optional
but
but
if
if
you're
you're
running
running
a
a
lot
lot
of
of
tasks,
tasks
you
you
might
might
want
want
to
to
just
just
max
max
out
out
the
the
memory.
memory
And
and
then
then
we'll
we'll
call
call
pubsubschedule,
pubsubschedule
and
and
for
for
the
the
schedule,
schedule
we'll
we'll
pass
pass
all
all
stars
stars
or
or
wildcards.
wildcards
This
this
will
will
have
have
the
the
function
function
tick
tick
every
every
1
1
minute,
minute
And
and
that's
that's
actually
actually
the
the
max
max
level
level
of
of
granularity
granularity
that
that
you
you
can
can
achieve
achieve
with
with
a
a
crontap
crontap
schedule.
schedule
It's
it's
likely
likely
that
that
we
we
want
want
to
to
run
run
a
a
lot
lot
of
of
different
different
jobs
jobs
concurrently.
concurrently
So
so
we'll
we'll
do
do
this
this
inside
inside
of
of
an
an
async
async
function,
function
and
and
then
then
we'll
we'll
want
want
to
to
get
get
the
the
current
current
time
time
as
as
represented
represented
by
by
a
a
Firestore
firestore
time
time
stamp.
stamp
We
we
can
can
use
use
this
this
to
to
query
query
Firestore
firestore
for
for
every
every
job
job
that
that
has
has
a
a
perform
perform
at
at
timestamp
timestamp
in
in
the
the
past.
past
Those
those
are
are
the
the
jobs
jobs
that
that
we
we
want
want
to
to
run
run
right
right
now.
now
And
and
then
then
we'll
we'll
also
also
make
make
sure
sure
that
that
each
each
task
task
is
is
scheduled
scheduled
because
because
we
we
don't
don't
want
want
to
to
run
run
a
a
job
job
that's
that's
already
already
been
been
completed.
completed
This
this
will
will
make
make
it
it
a
a
composite
composite
query,
query
so
so
keep
keep
in
in
mind
mind
you'll
you'll
need
need
an
an
index
index
in
in
Firestore
firestore
to
to
run
run
this
this
query.
query
The
the
next
next
thing
thing
we'll
we'll
do
do
is
is
read
read
this
this
collection
collection
by
by
calling
calling
await
await
query
query
get,
get
and
and
then
then
we're
we're
going
going
to
to
make
make
sure
sure
that
that
each
each
job
job
is
is
a
a
promise.
promise
So
so
I'm
i'm
creating
creating
an
an
empty
empty
array
array
here
here
that
that
will
will
be
be
an
an
array
array
of
of
promises
promises
that
that
we
we
Can
can
execute
execute
concurrently.
concurrently
From
from
there,
there
I'll
i'll
loop
loop
over
over
every
every
document
document
in
in
the
the
collection,
collection
and
and
from
from
each
each
document,
document
I
i
want
want
the
the
worker
worker
function
function
name
name
as
as
well
well
as
as
any
any
options
options
that
that
we
we
need
need
to
to
pass
pass
into
into
that
that
function.
function
We
we
haven't
haven't
defined
defined
the
the
worker
worker
functions
functions
yet,
yet
but
but
we'll
we'll
do
do
that
that
in
in
the
the
next
next
step.
step
It's
it's
simply
simply
going
going
to
to
be
be
an
an
object
object
that
that
has
has
a
a
series
series
of
of
functions
functions
on
on
it,
it
so
so
we
we
can
can
call
call
those
those
functions
functions
based
based
on
on
the
the
object's
object's
Property
property
name.
name
Now
now
because
because
we're
we're
going
going
to
to
force
force
each
each
worker
worker
function
function
to
to
return
return
a
a
promise,
promise
we
we
can
can
run
run
them
them
all
all
concurrently,
concurrently
and
and
we
we
can
can
also
also
handle
handle
the
the
success
success
and
and
error
error
cases
cases
in
in
a
a
way
way
that's
that's
generic
generic
So
so
we
we
can
can
handle
handle
it
it
the
the
same
same
way
way
for
for
every
every
job
job
that's
that's
enqueued
enqueued
no
no
matter
matter
what
what
its
its
business
business
logic
logic
is
is
doing.
doing
In
in
this
this
case,
case
we'll
we'll
just
just
go
go
ahead
ahead
and
and
update
update
the
the
underlying
underlying
document
document
to
to
a
a
status
status
of
of
complete,
complete
or
or
if
if
it's
it's
an
an
Error
error
will
will
update
update
it
it
to
to
a
a
status
status
of
of
error.
error
And
and
lastly,
lastly
we'll
we'll
go
go
ahead
ahead
and
and
push
push
it
it
to
to
the
the
jobs
jobs
array.
array
And
and
the
the
final
final
thing
thing
we
we
need
need
to
to
do
do
from
from
our
our
task
task
runner
runner
is
is
just
just
return
return
promise
promise
dot
dot
all
all
with
with
the
the
jobs
jobs
array.
array
So
so
that's
that's
all
all
it
it
takes
takes
to
to
create
create
a
a
basic
basic
task
task
runner
runner
with
with
this
this
new
new
PubSub
pubsub
function
function
type
type
and
and
Firestore.
firestore
Now
now
it's
it's
time
time
to
to
define
define
the
the
business
business
logic
logic
for
for
the
the
task
task
runner.
runner
The
the
logic
logic
will
will
be
be
kept
kept
in
in
this
this
workers
workers
object,
object
and
and
I'm
i'm
going
going
to
to
create
create
an
an
interface
interface
for
for
this
this
object
object
because
because
it
it
has
has
a
a
specific
specific
signature
signature
that
that
it
it
needs
needs
to
to
follow.
follow
The
the
keys
keys
can
can
be
be
any
any
value.
value
That's
that's
the
the
name
name
of
of
the
the
function.
function
And
and
then
then
the
the
function
function
itself
itself
has
has
an
an
options
options
object,
object
which
which
we
we
can
can
use
use
to
to
pass
pass
in
in
any
any
dynamic
dynamic
data
data
to
to
the
the
function
function
at
at
runtime.
runtime
And
and
that
that
corresponds
corresponds
to
to
the
the
options
options
map
map
on
on
the
the
Firestore
firestore
document.
document
And
and
lastly,
lastly
we
we
want
want
to
to
enforce
enforce
that
that
each
each
worker
worker
function
function
returns
returns
a
a
promise.
promise
Now
now
we'll
we'll
go
go
ahead
ahead
and
and
define
define
the
the
worker's
worker's
object,
object
and
and
we'll
we'll
give
give
it
it
a
a
key
key
of
of
hello
hello
world,
world
which
which
is
is
a
a
function
function
that
that
just
just
returns
returns
a
a
right
right
to
to
the
the
Firestore
firestore
database.
database
Let's
let's
go
go
ahead
ahead
and
and
deploy
deploy
our
our
function
function
and
and
make
make
sure
sure
the
the
task
task
runner
runner
is
is
working.
working
We'll
we'll
go
go
into
into
Firestore
firestore
to
to
the
the
task
task
collection,
collection
set
set
the
the
worker
worker
to
to
hello
hello
world,
world
Then
then
set
set
the
the
status
status
to
to
scheduled
scheduled
and
and
the
the
time
time
stamp
stamp
to
to
sometime
sometime
in
in
the
the
past.
past
After
after
that,
that
we
we
just
just
need
need
to
to
wait
wait
about
about
a
a
minute
minute
and
and
then
then
we
we
should
should
see
see
the
the
status
status
flip
flip
to
to
complete.
complete
And
and
then
then
we
we
should
should
also
also
see
see
this
this
hello,
hello
world
world
document
document
in
in
the
the
logs
logs
collection.
collection
In
in
the
the
original
original
video,
video
this
this
is
is
the
the
point
point
where
where
we
we
built
built
the
the
robocaller,
robocaller
but
but
I'm
i'm
just
just
gonna
gonna
go
go
ahead
ahead
and
and
wrap
wrap
things
things
up
up
here.
here
The
the
important
important
takeaway
takeaway
is
is
that
that
you
you
now
now
have
have
a
a
system
system
that
that
can
can
schedule
schedule
any
any
back
back
end
end
code
code
dynamically.
dynamically
Some
some
good
good
use
use
cases
cases
might
might
be
be
allowing
allowing
users
users
to
to
schedule
schedule
push
push
Vacations,
vacations
reminders,
reminders
or
or
transactional
transactional
email,
email
but
but
Definitely
definitely
not
not
robo
robo
callers.
callers
If
if
this
this
video
video
helped
helped
you,
you
please
please
like
like
and
and
subscribe,
subscribe
and
and
consider
consider
becoming
becoming
a
a
pro
pro
member
member
at
at
FireShip
fireship
IO
io
to
to
get
get
access
access
to
to
even
even
more
more
content.
content
Thanks
thanks
for
for
watching,
watching
and
and
I
i
will
will
talk
talk
to
to
you
you
soon.
soon
success
The speakers discuss the use of a robocaller video and how it can be used to schedule tasks, integrating Fir emp to create a new task generator, and create a new function type called Pub sub-function. They also explain how to optimize cost and create a task collector by passing data into the back end function and the importance of keeping the schedule static. The process for executing a task runner is discussed, including defining jobs and using a queue to queue, and the use of a worker function and the need for a back end code to schedule code dynamically. Viewers are encouraged to consider becoming a pro member and thanked for watching.
Scheduled Cloud Functions - NOT for Robocallers
Yesterday, you may have seen a video about building an industrial scale robocaller. I decided to take that video down and destroy all the physical copies because even though it's an obvious joke, it's not the right way to be using those tools. But the good news is that I recut that video, and it keeps the most important part intact, which is building a scheduled task queue with Firebase Cloud Functions. And make sure to leave a comment on this Video for the t shirt giveaway, even if you left a comment on the original. And lastly, I just want to take a second to say thank you for supporting the channel. 2019 has already exceeded my Rectations and the video idea list seems to get longer and longer. Just don't expect any robo color tutorials anytime soon. Tell him to call me ASAP as possible. Thanks. Americans get at least 5,000,000,000 spam robocalls per month, and that number gets bigger and bigger every year. Personally, I get at least 10 of those calls per day, and I finally just decided if you can't beat them, join them. In today's video, we're going to not build a robo column using and a brand new Cloud Function type from Firebase. But more importantly, we're going to build a task runner that allows us to schedule any back end code to run at any If you're new here, like and subscribe, and you can find the full source code on Fireship IO. And leave a comment below for a chance to win this one of a kind t shirt next week. So Firebase released a new function type a couple days ago. It's a PubSub function, which allows you to pass messages in between Google services that is also integrated with Google Cloud Scheduler. This means you can run any back end code at a specific point in time using a crontab schedule. This is great if you know exactly when you wanna schedule a job in advance, But I want to push things a step further by integrating Firestore to create a dynamic task runner that allows you to schedule a job at any point in time. That allows you or your users to schedule anything Dynamically, such as notifications, reminders, or as we'll see soon Definitely not robo callers. Make sure you have the latest version of Firebase Tools installed version 6.7 or version 2.3 of the Firebase functions module. From there, we can initialize a new project by running Firebase init functions. I'll be using TypeScript, and you'll see why it's so valuable for a project like this in a few minutes. Let's start by taking a look at a basic scheduled pubsub function. In the index. Ts, I have a reference to the admin SDK as well as Firestore, which we'll be using later. To create a scheduled function, we'll call functions.pubsub. Scheduled. The scheduled method takes a crontab schedule as its argument, which itself is just a string with 5 slots that represent the minute, hour, day, month, and weekday of the schedule. In my code here, I have the minutes set to 30 and the hour to 5, so this will tick at 5:30 AM every day. But I wouldn't recommend trying to memorize how Cron schedules work because there's this app called Chrontap Guru that makes it easy to edit and customize Cron schedules. From there, we just call on run. That gives us access to a callback function which can execute background code on the schedule. That's easy enough, but our schedule is static, so what if we want to change the Schedule or allow the user to schedule something dynamically. In this demo, we want to build a robocaller that can scale up to millions of phone calls per day and schedule those calls at different times throughout the day. For that, we're going to build a dynamic task runner and we'll start by modeling the data with Firestore. We'll create a task collection And each document will represent a job that we want to run-in the background at a specific point in time. The first field you'll see here is worker, which is just a string that represents a JavaScript function that lives somewhere in our back end code. The worker handles all of the business logic, And the Firestore document is really just a messenger to pass data to the back end. The next field is status. This will just tell us whether or not a task has been completed or whether or not scheduled or maybe it errored out. The next field is perform at, which is a time stamp that tells us when to execute this task. You'll wanna make sure that this is a Firestore Store time stamp to ensure it's consistent across all of your clients. Then the 4th and final field is options, which is just a map that allows us to pass any serialized data into the back end function. Chen. So what we're going for here is a generic system that allows us to name a function and then pass some data to that function and have it run securely in the back again on a specific schedule that can be user defined if you create this document in the front end. That's how we get data to the back end. Now we need to execute it by defining a task runner. This is simply a scheduled function that runs every 60 seconds and checks to see if we have any jobs that need to be executed. This function will be invoked about 45,000 times per month, which is well within the free tier on Firebase if you're worried about cost. And you can even use this to optimize cost because you can run multiple jobs within a single function invocation. I'm I'm gonna go ahead and create a function called Task Runner, and I'm going to increase the memory to 2 gigabytes. That part's completely optional, but if you're running a lot of tasks, you might want to just max out the memory. And then we'll call pubsubschedule, and for the schedule, we'll pass all stars or wildcards. This will have the function tick every 1 minute, And that's actually the max level of granularity that you can achieve with a crontap schedule. It's likely that we want to run a lot of different jobs concurrently. So we'll do this inside of an async function, and then we'll want to get the current time as represented by a Firestore time stamp. We can use this to query Firestore for every job that has a perform at timestamp in the past. Those are the jobs that we want to run right now. And then we'll also make sure that each task is scheduled because we don't want to run a job that's already been completed. This will make it a composite query, so keep in mind you'll need an index in Firestore to run this query. The next thing we'll do is read this collection by calling await query get, and then we're going to make sure that each job is a promise. So I'm creating an empty array here that will be an array of promises that we Can execute concurrently. From there, I'll loop over every document in the collection, and from each document, I want the worker function name as well as any options that we need to pass into that function. We haven't defined the worker functions yet, but we'll do that in the next step. It's simply going to be an object that has a series of functions on it, so we can call those functions based on the object's Property name. Now because we're going to force each worker function to return a promise, we can run them all concurrently, and we can also handle the success and error cases in a way that's generic So we can handle it the same way for every job that's enqueued no matter what its business logic is doing. In this case, we'll just go ahead and update the underlying document to a status of complete, or if it's an Error will update it to a status of error. And lastly, we'll go ahead and push it to the jobs array. And the final thing we need to do from our task runner is just return promise dot all with the jobs array. So that's all it takes to create a basic task runner with this new PubSub function type and Firestore. Now it's time to define the business logic for the task runner. The logic will be kept in this workers object, and I'm going to create an interface for this object because it has a specific signature that it needs to follow. The keys can be any value. That's the name of the function. And then the function itself has an options object, which we can use to pass in any dynamic data to the function at runtime. And that corresponds to the options map on the Firestore document. And lastly, we want to enforce that each worker function returns a promise. Now we'll go ahead and define the worker's object, and we'll give it a key of hello world, which is a function that just returns a right to the Firestore database. Let's go ahead and deploy our function and make sure the task runner is working. We'll go into Firestore to the task collection, set the worker to hello world, Then set the status to scheduled and the time stamp to sometime in the past. After that, we just need to wait about a minute and then we should see the status flip to complete. And then we should also see this hello, world document in the logs collection. In the original video, this is the point where we built the robocaller, but I'm just gonna go ahead and wrap things up here. The important takeaway is that you now have a system that can schedule any back end code dynamically. Some good use cases might be allowing users to schedule push Vacations, reminders, or transactional email, but Definitely not robo callers. If this video helped you, please like and subscribe, and consider becoming a pro member at FireShip IO to get access to even more content. Thanks for watching, and I will talk to you soon.
The speakers discuss the use of a robocaller video and how it can be used to schedule tasks, integrating Fir emp to create a new task generator, and create a new function type called Pub sub-function. They also explain how to optimize cost and create a task collector by passing data into the back end function and the importance of keeping the schedule static. The process for executing a task runner is discussed, including defining jobs and using a queue to queue, and the use of a worker function and the need for a back end code to schedule code dynamically. Viewers are encouraged to consider becoming a pro member and thanked for watching.