Google Cloud Tasks is provided by Google Cloud Platform (GCP). It is a fully managed service that allows you to create, manage, and execute asynchronous tasks in a reliable and scalable way. These tasks are independent pieces of work that are to be processed outside your application flow using handlers that you create. These handlers are essentially the endpoints or services that process your tasks. You can use HTTP, app engine, pub/sub, or even custom backend handlers. In this article, we will look through the cloud task workflow and how to effectively schedule cloud functions using cloud tasks.
How does Google Cloud Tasks WorkGoogle Cloud Task is essentially used to manage the execution of asynchronous tasks on a high level. Here is a step-by-step description of its workflow:
Tasks Creation:Your application creates a task with specific data (payload) and adds it to a task queue.
You can specify:
Tasks are stored in a queue until they are ready to be executed. With queues, you can organize tasks by priority or function.
Tasks Execution:When a task is ready to execute (immediately or after a specified delay), Google Cloud Tasks sends the task to the specified handler.
\ Handlers can be:
The handler processes the task using the data provided in the task payload. After processing, the handler responds with a success or failure status. If successful, the task is marked as complete and removed from the queue else, the task is retried based on the retry policy.
\ You can monitor the status of tasks and queues using the Google Cloud Console or APIs.
Google Cloud Tasks vs Google Cloud SchedulerGoogle Cloud Scheduler is a fully managed cron job service provided by Google Cloud Platform (GCP). It allows you to schedule and automate the execution of tasks, such as running scripts, triggering APIs, or executing Cloud Functions, at specified times or intervals.
\ Here is a comparative analysis of Google Cloud tasks and Google Cloud Scheduler, understanding what these two services offer will help you choose what service is the best fit for your project.
Comparative Analysis: Google Cloud Scheduler vs. Google Cloud Tasks| Aspect | Google Cloud Scheduler | Google Cloud Tasks | |----|----|----| | Purpose | Automates and schedules recurring tasks or cron jobs. | Manages asynchronous or one-off tasks with controlled execution. | | Task Execution | Executes tasks based on a fixed schedule (e.g., hourly, daily). | Executes tasks triggered by application events or logic. | | Concurrency | Executes tasks one at a time per job. | Can handle multiple tasks concurrently with queue management. | | Scalability | Suitable for a moderate number of scheduled jobs. | Highly scalable for managing thousands of tasks. | | Example Scenario | Run a database cleanup script every Sunday at midnight. | Queue a task to process an image upload triggered by a user action. |
Schedule Cloud Function using Cloud TasksIn this example, we will go through the process of creating a cloud function that is to be evoked at a later time using cloud tasks.
PrerequisitesTo make the most of this tutorial, you should have the following:
Google Cloud Platform (GCP) project with billing enabled
A good understanding of Cloud functions and Typescript
\
Once you’ve checked off all the prerequisites, enable the Google Cloud Tasks API from the Google Cloud console.
\
\ Once this has been successfully enabled, create a queue. You can create a queue with Google Cloud (gcloud) CLI or right there in the Google Cloud console. To create a queue via gcloud CLI then you have to first install the gcloud SDK and have it configured to your Firebase project. Once it’s been configured, run this command from the terminal to create your queue.
\
gcloud tasks queues create QUEUE_ID --location=LOCATION\ Replace QUEUE_ID and LOCATION with your preferred values. For more details on queue creation via gcloud CLI, see here.
\ To create a queue directly from Google Console, navigate to Cloud Tasks and click on the create queue option to create your queue.
\
Now that Cloud Tasks has been set up you can now use it in your functions. To use, first install the Cloud Task client.
npm install @google-cloud/tasks\ In this example, we will create a cloud function that sends emails to the email addresses in our Firestore collection. Using Google Cloud Task, we will schedule this cloud function to be called at a specified time. Let’s dive in.
\ Install nodemailer, because we will first create a sendEmail function.
npm install nodemailer\ Here is the send email function:
import * as functions from "firebase-functions"; import * as admin from "firebase-admin"; import * as nodemailer from "nodemailer"; import {OAuth2Client} from "google-auth-library"; admin.initializeApp(); const transporter = nodemailer.createTransport({ service: "gmail", auth: { user: "[email protected]", pass: "sender pass", }, }); /** * This function sends emails. */ export const sendEmail = functions.https.onRequest(async (req, res) => { const projectId = JSON.parse(process.env.FIREBASE_CONFIG!).projectId; const location = "us-central1"; const authorizationHeader = req.headers.authorization; if (!authorizationHeader) { res.status(401).send("unauthorized token"); return; } // if authorizationHeader is not null access the token const token = authorizationHeader.split(" ")[1]; // verify ID token try { await verifyToken(token, location, projectId); } catch (error) { console.log(error); res.status(401).send("Unauthorized token"); return; } try { const snapshot = await admin .firestore() .collection("email_addresses") .get(); if (snapshot.empty) { res.status(404).send("No email addresses found in the collection."); return; } const emailAddresses: string[] = []; snapshot.forEach((doc) => { const data = doc.data(); if (data.email) { emailAddresses.push(data.email); } }); if (emailAddresses.length === 0) { res.status(404).send("No valid email addresses found."); return; } const promises = emailAddresses.map((email) => { const mailOptions = { from: "[email protected]", to: email, subject: "Welcome to Our Service!", text: `Hello, ${email}! Welcome to our platform. We're excited to have you on board!`, }; return transporter.sendMail(mailOptions); }); await Promise.all(promises); res.status(200).send("Emails sent successfully!"); } catch (error) { console.error("Error sending emails:", error); res.status(500).send("An error occurred while sending emails."); } });\ This function extracts the list of email addresses in the collection and then using the nodemailer, it sends emails to every one of those email addresses. This function also has an auth guard which prevents it from being called by those that aren’t authorized. This auth guard first checks if the auth token is contained in the header, if not it throws an error. However, if a token is contained, using the verifyToken function, it verifies it.
\ For the verifyToken function install the google-auth-library. This is what will be used to verify the token.
npm install google-auth-library\ \
/** * This function verifies token * @param {string} token * @param {string} location * @param {string} projectId * @return {PromiseAll Rights Reserved. Copyright , Central Coast Communications, Inc.