Firebase Cloud Function

Posted by Shi

Firebase Cloud Function

Deploy

All functions

firebase deploy --only functions

A certain function

firebase deploy --only functions:functionNameThatYouWantToDeploy

Run cloud function locally

  1. start
firebase functions:shell
  1. invoke a function
toUpperCase('first task')

Logs

console.log("");
console.info("");
console.warn("");
console.error("");
console.debug("");

Error reporting

throw new Error("A failure")

Firebase Functions: Fundamentals

by Ervis Trupja

Firebase Functions provide an easy way for developers to run and scale code in the cloud and build event-driven serverless applications. This course will teach you how to create Firebase functions using javascript and typescript.

Resume CourseBookmarkAdd to ChannelDownload Course

Course Overview

Course Overview

Hi everyone, and welcome to my course, Firebase Functions: Fundamentals. My name is Ervis Trupja, and I’m a self-employed web developer and trainer. In this course, we are going to talk about cloud functions for Firebase. It’s a great service which allows us to run back-end code in response to events triggered by Firebase features and HTTP requests. Some of the major topics that we will cover include understanding cloud functions, calling, triggering, and writing Firebase functions, testing Firebase functions, and upgrading Firebase functions. By the end of this course, you’ll know enough to take advantage of the amazing Firebase functions as a serverless compute solution for creating event-driven applications. Having previous experience with other Firebase services is recommended, but it is not required. I hope you will join me on this journey to learn Firebase functions with the Firebase Functions: Fundamentals course here, at Pluralsight.

Getting Started

Getting Started

Hi, and welcome to my course, Firebase Functions: Fundamentals. I am Ervis Trupja, and together we are going to explore Firebase functions. Cloud functions for Firebase is a Firebase service which lets you automatically run back-end code in response to events triggered by Firebase features and the HTTP requests. There is no need to manage and scale your own servers because your code is stored in Google’s cloud and runs in a managed environment. But what are wegoing to learn on this course? We are going to start with the basic concepts of the cloud functions. We will give examples so we can better understand it. Thenlater, we will learn how to call a Firebase function, how to trigger, write, test, and monitor Firebase functions. And at the end of this course, assuming that you already have experience with the previous versions of Firebase functions, we are going to learn how to upgrade to the latest version. So let’s get started.

What Is Firebase?

Before we start learning about Firebase functions, it is important to know what Firebase itself is, and Firebase is a platform. We use the Firebase to build,improve, and grow our apps because the tools that it gives us cover a large portion of the services that we, as developers, would normally have to buildourselves. Some of the services that Firebase offers are Firebase Firestore, Firebase Realtime database, Firebase authentication, and the one that we are going to talk about on this course is the Firebase functions. The Firebase services are hosted in the cloud, and with cloud, I mean that the products have back-endcomponents that are fully maintained and operated by Google. Then we have the client SDKs, which are provided by Firebase to interact with these back-endservices directly with no need to establish any middleware between your app and the service. So for example, if you are using one of the Firebase databaseoptions, you typically write the code to query the database in your client app. Now this is different than the traditional app development, which typically involves writing both frontend and the backend, and then the back-end code does the work. But with Firebase products, the traditional backend is bypassed putting the work into the client. So let us get started and learn about the Firebase functions.

Prerequisites

To get the most out of this course, there are a couple of tools and technologies which will be really helpful if you have previous experience with. For development, we are going to use Visual code. So if you want to follow along while coding, make sure that you have installed this application. Also, we are going to use both JavaScript and TypeScript to write functions. Having experience is recommended, but it is not required in any way because I will show you step by step how to create the functions. Other than that, we are going to use Firebase CLI for different configurations, deployments, etc, but still, it’s just a preferred skill, not required one.

Why Should You Learn Firebase Functions?

Why should you learn Firebase functions? The main reason for using Firebase functions, in my opinion, is because it integrates perfectly with the other GoogleCloud features. You can use it with different triggers like, for example, real-time database triggers, Cloud Firestore, authentication, etc. When using Firebase functions, it is great because once you deploy your JavaScript and TypeScript code, you do not have to worry about the computing resources because they are automatically scaled up. You don’t have to ever worry about the credentials, server configurations, provisioning new servers, etc. Also, cloud functions are fully insulated from the clients which makes it a secure technology to be used.

How Does It Work?

After you write a function and deploy it to the Firebase hosting, you can immediately use that function and you can either call it directly or over an HTTPrequest. We are going to talk about these topics later. So you, as a developer, you create a function by defining the behavior, the conditions, etc, then youpublish this function so it’s available to be used. And finally, when an event is triggered, the function is invoked. So let us say, for example, we want to trigger afunction whenever somebody tries to add something in the Cloud Firestore. In this case, we will create a function, we will deploy this function, and we will invoke this function whenever a change occurs. If the function is busy handling many events, then Google will create for you more instances to handle the work faster. And if the function is idle, instances are cleaned up. But what happens when you update or you want to delete an existing function? Let us say you deployed you function and now you want to update it. When you update the function, all the instances for the old version are cleaned up and replaced by the new instances, and when a developer deletes a function, all the instances are cleaned up and the connection between the function and the event provider, let’s say Cloud Firestore, is removed. You don’t have to worry about these concepts at the moment because in the upcoming modules, we are going to illustrate them one by one. But it’s important to know that to implement the function in Firebase functions, you first set up the cloud functions, you write your function, and then you deploy it.

Setting up Node.js and Firebase CLI

During this course, we are going to use the Firebase CLI. The Firebase CLI makes it easy to set up in your Firebase functions project, run local developmentserver, and deploy content. But use Firebase CLI. We need to install Node.js Server as well. Cloud functions can run on either Node version 6 or Node version 8.If you have existing functions built on Node version 6, you can continue to use that version. Otherwise, you can install the latest version of the Node.js. Let usstart this part by installing the Node.js and the Firebase CLI. To install the Node.js Server, you can go to the nodejs.org URL and here you will get two options, the recommended version, which is the latest stable version, and the latest version as well. I have already installed Node.js, and if you have not, you can simply download it in here and install it. To check which version of Node.js you have installed, open the command prompt window. In here, type node -v where v stands for version. If you press Enter, you will see that I have installed the version 8.11 .3. Since I have already installed Node.js, I can use the node package manager to install the Firebase CLI, and to install Firebase CLI, go to your working directory. And after you navigate to your working directory, in here, type npm install -g, which stands for globally, so you install the Firebase CLI one time and then it’s accessible from anywhere within your working directory. And then just write in here firebase tools, so firebase -tools. And then next, press Enter. So you will have to wait for a couple of seconds for the Firebase tools to be installed. So now that the Firebase CLI is installed, let us create our first function.

Creating Your First Function

To create a Firebase function, the first thing that we need to do is that we need to initialize a Firebase project. So let us see in action how we can initialize aFirebase functions project and how we can create a Firebase function. For that, let us go to our working directory. In your working directory, run the firebase login command to log in via the browser and authenticate the Firebase tool, so firebase login and then press Enter. So I see that I’m already logged in, but ifnot, I’m going to be prompt with a window to enter my credentials so I can easily log in and configure my Firebase tool. And before we proceed further, let us create a Firebase project which we are going to use along this course. So for that, go to the Firebase on google.com, click the Go to console button, click in here the Add project button, then provide a name. I’ll name my project My Functions, and you’ll see that a project ID will be automatically generated. I’ll leave the locations by default, then I will accept the terms and click Create project button. So now that the Firebase project is created, we are ready to configure theFirebase functions. So let us go back to the working directory and here we’ll type firebase init functions and then press Enter. Answer with yes to the firstquestion or you can simply press the Enter button. And from here, select a project, I’m going to select the project that we just created, which is the My Functions project, and then press Enter. Now you’ll be asked to choose the development language. I’m going to choose JavaScript because we are going to learn about TypeScript in an upcoming part. So I press Enter in here and then Enter one more time. Enter one more time to install the dependencies with the Node Package Manager and then I wait for a couple of seconds for all the dependencies to be installed. So that now everything is installed, I can open the project by using the Visual code by typing in here code. and then press Enter and my project is opened automatically. In here, by default, we are going to see a couple of files. The first file that we see in here is the .firebaserc and this file will continue the projects that we want to configure. This file will help us to quickly switch between projects using the firebase use command if we want to. The other file that we have in here is the Firebase.json file, and in this file, we describe the properties of our project. At the moment, we don’t have any properties in here. We also see in here that we have a functions folder, and inside this functions folder, we have the node_modules that we just installed using the npm. We have the index.js file, which is the main source file for your cloud functions, then wehave the package.json file and the package.json file is a file describing your cloud functions. So for example, if I type in my command firebase serve, these are the commands that I’m going to execute. And then if I have time, for example, firebase start, I’m going to actually run the npm run shell command, etc. To create a function, go to the index.js file, and in here, you can simply uncomment these lines of code. So we have the helloWorld function, which is just a function which is going to be triggered when we request it using an HTTP request and it’s going to just respond to our browser with the response.send and here wehave the Hello from Firebase message. This is just a demo because on the upcoming modules we are going to create functions step by step, but for the moment, it’s important to know that to make a function accessible, we use the exports keyword and the function name. And then in here, we define the function is a callable function or if it’s a function that we can trigger on a request and we are going to talk in more details about functions in the upcoming parts. Now that we created a function, let us deploy this function, and to deploy a function, simply open the terminal, and in here, type firebase deploy, use the only flag if you want to deploy only functions, so only functions. So now that the function was successfully deployed, we see that we can access it from this URL. The first part is the us-central, then we have the projects id, .cloudfunctions .net / our function. To see the result, we can copy this link, go to any browser of your choice, I’ll use Google Chrome, and then in here, open a new tab, paste this URL and press Enter. And here you see the Hello from Firebase message that we defined in our function.

Summary

On this module, we talked about the Firebase functions and we learned that Firebase functions are great because they integrate perfectly with the Firebaseplatform. Also, we don’t have to maintain any servers after we deploy our functions because Google will take care of that and the logic is kept private, which makes the Firebase functions really secure. Later, we’ll learn how to install Node.js and Firebase CLI and we need the Firebase CLI for different configurations, for different deployments, and much more. And at the end of this module, we learned how to create a function and how to deploy it. Even though we use the default template, in the upcoming modules, we are going to talk about functions and how to create them step by step. We are also going to learn how to create different types of functions and how to trigger them from different events. So this was all for this module. See on the next ones.

Calling Functions Directly

Introduction

Hi, and welcome to the second module of these tutorials. In here, we are going to talk about calling Firebase functions directly. We are going to first create acallable function, and after we create this function, we are going to learn how to set up the client part so we can call this function. And then next, we are goingto learn how to trigger functions with an HTTP request, and at the end, we are going to learn how to terminate an HTTP function.

Creating a Callable Function

The cloud functions for Firebase client SDKs. Let us call functions directly from a Firebase application. Now to call a Firebase function from your application,you need to write and deploy a callable function in the cloud functions, and then next, we need to add client logic to call the function from our application.Callable functions are similar to other HTTP functions, but additionally with callables, if available, Firebase authentication is included in the request and the trigger will automatically deserialize the request body and validate the authentication tokens. To create a callable function, we need to use the function onCall. This method will take two parameters, a data, and then optional context. So let us create our first callable function. Let us first make sure that we are already logged in, so for that, write firebase login, so firebase login, and then press Enter. So we see that we are already logged in. Now let us configure Firebase functions, so for that, firebase, then init, and then functions. Press Enter, then choose a default project. I’m going to choose the StaffProject, but you can create any project of your choice. Then I’m going to select JavaScript, and then at the end, press Enter one more time to install all the dependencies. Now that everything is set up, go to the functions folder. Inside the functions folder, you are going to see an index.js file, and inside this file, we are going to create the first callable function. To create a callable function, we need to first define the name of the function, so for that, we write exports and then. define the name, which is going to be addPerson. So functions.https and then onCall. We said that it takes two parameters so the data and the context and now we can work with the data and the context of this function. So let us say from the data we are going to send a first name and a last name, so for that, we write var firstName is going to be data. give the property firstName from the data and then the lastName, so we change this to lastName and then data.lastName. So we have the first name and the last name. What we want to do now is that we want to return the full name to the users as well. So for that, we write return and then inside curly brackets write firstName is going to have a value of the firstName that we created in Line 11, comma, then last name is going to be our lastName. Let us add one more field, which is going to be fullName and this is going to be a combination of firstName separated by a space, and then lastName. So this is all you need to do to create a callable function. Now so far, we are just creating the function and returning something so we are not storing any data in a real timedatabase, but we are going to talk about that later. And now let us deploy this function. So for that, in your terminal, write firebase deploy –only functions andthen you can define the name of the function that you want to deploy, so I want to deploy the addPerson function, so for that, write addPerson and then pressEnter. The function was deployed successfully. So if you go in the Firebase console on the Project Overview, then go to the Functions menu item, on theDashboard tab, you’re going to see that now we have a function named addPerson. So this is before you publish a function to Firebase and then you trigger this function from your client, but let’s see how we can trigger this function on the next part.

Setting up a Client Environment

On the last part, we created the function and then we deployed this function to our Firebase project. Now let us see on this part how we can call that function from a client application. In here, let us go to the index.html file, which is empty at the moment, so it doesn’t have anything, it just has a button, and when we click this button, we are going to execute a function named addEmployee. Now this addEmployee will have a value of the firstName and the lastName, which we get from these two input text boxes. When working with Firebase callable functions, the first thing that we need to do is that we need to make sure that we have initialized the client SDK, and to initialize the Firebase SDK, let us go to Firebase console. And in the Project Overview page, go to the third option in here, which is web, and then click the Copy button. Now that we copied this code, let us go back to our application and paste it before our script tag. So here, we create a reference to the firebase.js file, and then next, we initialize the Firebase application. And the first thing that we need to do is that we need to create a reference to our callable function. So for that, let us write var addPerson is equal to firebase.functions so I want to create a reference to the functions in my Firebase project. And then from my functions, I want to get an HTTPS callable function. I write .https callable, and then inside parentheses, we need to define the name of the function and the name of the function is addPerson. For the addPerson, we have defined that the addPerson will take as a parameter some data. Now let us call this function with some data. So now we use the reference, and then inside curly brackets, we define the properties that we want to send, and we have said that we want to send a firstName and a lastName. So inside the index.html file, write firstName, then define the value to be this firstName andwe do the same for the lastName, so last, and we replace this firstName with the lastName in Line 21. So this is how you call the function. Now to get the response back right, then we are going to get the result. So we write the function, then result, and in case the request is successful, as a result, we are going toget this part. And what do we want to do with that. Let us console.log the result, so console.log and then the result. And in case something goes wrong, we want to catch the error, so for that, we write .catch and then we add in here a function error, so function and then error. Now we just want to simply console.log the error. Let us save the changes, right-click in here, and then go to the Reveal in Explorer. Then next, run your application. In here, provide a name, so it’s going to be Ervis and a last name, Trupja, and then click the Add person button. And in here, we’re going to see an object response, which inside has three properties. So first name is going to be my name, lastName, and a fullName, which is going to be my full name. Now with callable functions, you can do much more than just returning some data. You can actually use the callable functions to store some data in a database. So let us see how we can do that on the next part.

Storing Data in Firebase Realtime Database

So far, we have created the function and then we created the client app to execute this function, but the function just returns some data. What if we want tostore this data to a Firebase realtime database. So let us see how we can store data in a Firebase realtime database using a callable function. Let us go to theindex.js file and the first thing that we need to do is that we need to import the necessary requirements. And let us import the Firebase admin, so for that, you write const admin is equal to require, and then inside single quotes, write firebase -admin and initialize the firebase administrator apps, and for that, writeadmin.initializeApp, and that’s all you have to do on this part. Let us remove this comment because we are not going to use them and it goes to the Line 9 of this function. So instead of returning this object, we’re going to use this object to store it in a Firebase realtime database. So for that, we write returnadmin.database, so now we create a reference to the databases. Inside the database, I want to reference the persons, and then inside single quotes, write/persons. And what I want to do next is that I want to push some data, so I’m going to write .push, and then inside the push method, I’m going to put this object. So cut the object and paste it in here. And then to get a response, write .then, open curly brackets because I’m not interested in other response of thisfunction, I just want to check if it executes successfully. Open curly brackets, and inside here, write console.log New person added, and then let us just return Ok so we know that everything worked as expected. So when we write return Ok in here, it means that an index.html file when we have the function result that is going to be the value of the result so we are going to console.log, the Ok. Let’s go back to the index.html. But what happens when something goes wrong. When something goes wrong, we want to catch that. So let us write in here .catch. So we want to catch the default error. So for that, we write insideparentheses error and to ensure that the client gets useful error details, return errors from a callable by throwing an instance of the functions.https .HttpsError. So inside here, we write throw new and then functions.https .HttpsError. It helps us define the default properties in here, so it’s going to be an unknown. And then we want to display the error message, so for that, we write error.message. And then for details, let us return the error itself and let’s save the changes. But before you test this application, you need to make sure that you have already enabled the Firebase realtime database in your project. So for that, let us go to the Firebase console, and inside the Firebase console, go to the Database menu item. Then in here, click the Create database and then the Enable button. Then from the Database drop-down, change it from Cloud Firestore to Realtime database. Now let’s test our application. In here, I will leave just the default values and click the Add Person button. So we see that we still get the same response, even though we changed the function. Now the reason why we are getting the same response, even though we changed the function, is because we didn’t publish this function and the Firebase is not aware of our changes. So let us goback to our code, and in your terminal, execute the previous command one more time. So Firebase deploy on the functions and then define the addPerson function to be deployed and then press Enter. So the function was updated. Now let us go back to our application one more time, let us refresh the browser, and then leave the default values and click the Add Person button. Now we see that instead of the previous object, we are going to get a response Ok. Let us go to our database and see the result over there. So in here, now we see that we have the persons reference, and inside the persons, we’re going to see the first person so the firstName, the lastName, and the fullName. Let us keep this window on the side and add one more person. So I’ll write John Smith and I click the Add Person button and here we’re going to see that another person was added. Let’s add one more, click the button. So now we see a third person in our database.

Triggering Functions with an HTTP Request

In Firebase, you can trigger a function through an HTTP request by using the functions.https. This will allow you to invoke asynchronous function by using get,a post, a put, and a delete HTTP method. So we use the functions that HTTPS to create a function that will handle HTTP events. Now the event handler for the HTTP function will listen for the onRequest event, which will support router and apps managed by the express web framework. So let us see how we can create our first function, which we can call from an HTTP request. So we need to first define a function name, so for that, we write exports.date. So we are going to use this function to generate the datestamp at the moment that we call this function. And then write equal to functions.https .onRequest, which means that we can call this function over an HTTP request. Then define two parameters in here so the request and the response, and then inside the body of this method, we are going to create a const date variable. So const date is equal to new Date. Now that we have the date, we can create a reference to our database and then store this data over there. So let us write const snapshot so we can have a reference of our snapshot is equal to admin.database and then .ref, and then inside single quotes, write / and then dates. We want to store these values, so we want to push this value to our database. For that, we write .push, and then in here, let us send an object with one property. So now is going to be the property name and then date.toDateString. And then in here, let us write res.send and then let us display the same result in our browser so date.toDateString. Let us save the changes and publish this function. So we just need to change the function name in here from addPerson to date, and then press Enter. So we see that the function was successfully published. Now let us copy the function URL, go tothe browser, open a new tab, and paste it in here, and then press Enter. So in here, we are going to see the result. And if we go to our database, in here, acceptpersons, we are going to see the dates reference, and inside the dates, we are going to see the date. Let us execute it one more time. We have the same result,and in here, we are going to see another entry.

Terminating HTTP Functions

On the last part, we created a function which was returning a date and then we stored the date in a Firebase realtime database, but there is much more tofunctions in Firebase. So for example, you can read the values from the request and the modular request is going to automatically be pairs based on thecontent type pattern and we have some mostly used content types. So for example, when the content type has been defined to be application/json, then to get a value from the request, we can use the request.body. the property name. We can define the content type to be the octet-stream type, and then in this case,together value we can use the request.body, which will equal in a role bides value, but then we can use buffers to gather real data. Also, we can define the content type to be text-plain, and then in this case, we can use simply request.body, but instead of robot, we are going to have the value itself. We can also define a form content type, and that, in this case, to get the data out of the request, we can use the request.body. then the property name. So for example, if we have a property named name with a value of John, if we write request.body .name then John is going to be the response. It is important to mention that we need to always terminate HTTP functions, and to terminate an HTTP function, we need to always end an HTTP function with send, a redirect, or an end. Now the send is going to send a response back in our browser. So in the same URL, the redirect will be used to redirect us somewhere else and the end is used to quickly end request. So let us see what we can do with our previous function. So for that, let us go to the Visual Code project. So first of all, let us say that we don’t want to execute this function if the request method is not a get method. So for that, we can write in here if then request.method is different from get. We need to return a status. So this is a way to end this function. So you write return as a result, return a status of type 403 and then send a message to thebrowser forbidden. Let us say that after you have the snapshot, you don’t want to just return this response to the browser. You want to actually redirect the user to that snapshot. So for that, we need to use a response as well. So in here, write response.redirect. Inside the redirect, write 303, and what we want to send, we want to send the snapshot of the data. So for that, write snapshot.reference .toString. So these things that redirect us to the reference of the snapshot. Let us save the changes and publish the date function one more time. Let us go back to our application, and here, press Enter. So now we see that instead of seeing a response in our screen, we are being redirected to exactly that new date. And in here, we are going to see that result.

Summary

On this module, we talked about how to call functions directly. We started by first creating a callable Firebase function. So we roll functions and then wedeployed these functions to our Firebase project. And after we had created a callable function, we learned how to set up a client environment so we can actually call and use the response of this function. Then next we learned how to store data in Firebase Realtime database from a Firebase callable function. At the end of this module, we learned how we can work with functions via HTTP requests. So we learned how to trigger a function, how we can read values from requests, and then at the end, we learned how we can terminate functions. So I hope you have enjoyed what we have learned so far, and I hope to see you on the next module so see you on the next one.

Triggering Firebase Functions

Introduction

With Cloud functions, you can handle events in different Firebase services with no need to update the client code. And during this module, we are going to talkabout some of them. We are going to start with Cloud Firestore triggers, and if you want to learn more about Cloud Firestore, you can check out my course, Firebase Firestore: Getting Started. After that, we are going to work with realtime database triggers, and in here, we are going to see how we can set up a trigger and how to handle the event data. Next, we are going to talk about authentication triggers. And at the end, we will talk about Cloud storage triggers. We will see how to work with Cloud storage files and much more. So let’s get started.

Triggers on Cloud Firestore Changes

With Cloud functions, you can handle events in Cloud Firestore with no need to update the client code. And in a typical lifecycle, a Cloud Firestore function first waits for a change. It can be a document or a collection. Then a trigger happens when an event occurs, and then at the end, we can simply receive the data and work with this data. In Cloud Firestore, we can use the functions.firestore object, and by using this object, we can handle all the event types. We have the event onCreate and this event is triggered when a new document is created. Then next we have the onUpdate, and as the name already indicates, this is triggered when we update a document. Then next, we have the onDelete and this is triggered when a document with data is deleted. And the last one is the onWrite and this is triggered when any change happens in document so it’s triggered when onCreate, onUpdate, or onDelete. It is important to mention that Cloud Firestoreevents will trigger only on document changes, so it is not possible to add events to specific fields. Let us now create some functions which are going to be triggered when an event occurs. So for that, let us go to our Visual Code solution. In your Visual Code, go to the functions folder, and then here you have the index.js file. Let us now remove these lines of code because we are not going to use them. And in here, let us create a new section used for Cloud Firestore. So Iwill just write in here Cloud Firestore triggers. To create a function, we have said that we use the exports keyword and we want to create four functions. Let usname the first one staffAdded. And then we said that Firebase SDK exports the object functions.firestore to create handlers. So let us use that object, for that, we write functions.firestore. Then next, let us define a document, so for that we write .document, and then inside the single quotes, write staff, so we are searching for a document inside the staff collection. So then I’ll just write here staffId, which means it can be any document within the staff collection. And the first event type is going to be onCreate. So for that, we write .onCreate. Now this has two parameters, so the first one is going to be a snapshot or just snapand then context. And for the moment, let us just console.info that this event was triggered. So for that, write in here console.info and then A new staff memberwas added. We are going to do the same for the other events as well. So I’ll just copy these lines of code and then paste them here. I will change the onCreateevent to be onUpdate .onUpdate, and then change the name of the function from staffAdded to staffUpdated. And then next, change the A new staff member was added to staff member, or just a staff member, was updated. And now, let us do the same for the delete event. So I’ll just copy these lines of code, Ctrl+C, and then Ctrl+V to paste them here. Change the name of the function to staffDeleted and then change the event to be onDelete. In Line 15, change the was updated to was deleted. And we have the last one, which is onWrite, which is going to catch any type of event. So for that, change that to staffChanged, and then here onWrite, and then change the text to be A staff member was changed. Now that we created these functions, let us publish them, for that, Open in Terminal, and then in here, write firebase deploy –only, then functions: staffAdded, functions, so this will define all the functions, and press Enter. You need towait for a couple of seconds for all these functions to be published, and then next, you can go to the Firebase project to check all these functions. So in here, we see that all the functions were published successfully.

Handling Cloud Firestore Event Data

On the last part, we created some new functions, and then to these functions, we attached some event handlers. But what happens when any of the event handlers are triggered. We are going to see on this part how to handle the event data. So for example, we want to read some data. We want to see how the data looked like before we changed them, for example. Then next, we are going to see how we can write data back to Firebase Firestore, or you can even write data back to Firebase Realtime database. And then at the end, we are going to see how we can use wildcards and parameters when defining a path to Firebase Firestore. So let us see how we can handle the event data. In the project overview, go to the Functions menu item, then next, go to the Dashboard tab, and inhere, you are going to see the four new functions that we created. So here we have the staffAdded, we have the changed, the deleted, and the updated. Now to trigger these events, open the Database menu item. From the two options in here, choose the Cloud Firestore, and then add a collection. We are going to name the collection staff because we have created the event handlers on the staff collection and then click Next. I’ll leave the document ID to be automatically generated, and then next, I’ll just create a field named firstName and then assign a value, my value. Then click the Save button. So the collection, the document, and the document field were all created. Now let us go to the functions one more time and see what happens when we created a document. So if I go to the other tab, then go to the Logs tab, and then from the All functions drop-down, I’m going to choose the staffAdded, staffChanged, Deleted, and Updated, and then click Done. In here, you are going to see that we have multiple triggers executed. So the first one is that a staff member was changed and this one is executed on the onWrite event handler. Then we have the staffAdded because we added a staff member. Now let us go to the staff document and update thefield. So change the my value to my value new and then click the Update button. Now that we updated a staff document, we expect this staffUpdated function to be executed so we are going to see the A staff member was updated. If we go to the logs one more time, in here, we are going to see A staff member was updated. But what can we do with this data? Let us go back to the Visual code, and then inside the staffUpdated method, write. We want to see the new value and the old one, so for that we write const newValue, which means the value that we changed is equal to snap.after, so after the data was changed, and then .data. And then we can do the same to get the old value. So for that, we write const oldValue is equal to snap.before .data. So this is how you can get the data before it was changed and after it was changed. Now let us console.log the data. For that, we write new and then -newValue and we do the same for the old value. For that, we just write old and then oldValue. If you want to update an existing or create a new document, you write in here return and then snap.after, so get the latest date and then create a reference and set a value. Now in here, we are going to define that the value that we want to set is going to be a comment and the value of the comment is going to be Document updated. Let us define an additional property in here to be merged is equal to true, which means, just add this field in there if it does not exist, and if it exists, then simply update the content and then save the changes. Now since we made some changes to this function, let us update this function. For that, we write firebase deploy, then –only, and then functions:staffUpdated, and then press Enter. So the function was successfully updated. Let us go back to the Firebase console and then go to the Firebase Firestore and change the value of the first name to be just Ervis, or your first name, and then click the Update button. When we click the Update button, the staffUpdated function was executed and that function added in our document a new field named comment. If I change this field, let us say we changed this field to something else and click the Update button, the same thing is going to happen, so the comment is changed back to Document updated, or even if I delete this one, I’ll have the Document updated back. So this is how you can read the data and send some data. When it comes to wildcards, we have already used them in our functions. So in here, for example, we have defined that this event is going to be applied in all the staff members of the staff collection. And if you want to expand this even more, you can add other wildcards. So let’s say staffComment, for example, and then you can even define that for each comment the commentID, which means that inside this document, we are going tocreate a collection, and that inside this collection, we are going to have other different documents. Now this means that we are going to trigger this function for all the changes inside the collection.

Triggers on Realtime Database Changes

With cloud functions, you can handle events in Firebase Realtime database, the same like in the Cloud Firestore with no need to update the client code. So Cloud functions, let us run database operations and then make sure that each database change is proceeded individually. A typical Firebase Realtime database will first wait for a change in a database location, then triggers when an event occurs, so for example, when we add some new data, and then at the end, we can simply receive the data object that contains a snapshot of the datastore in that specific document. In Firebase Realtime database, we have different eventhandlers, the same like in the Cloud Firestore. So we have the onWrite, we have the onCreate, onUpdate, and onDelete. Let us start by first creating all thefunctions and then attaching to these functions the event handlers. In your project file, go inside the functions folder, then in the index.js file, we are going to create the new section. So before the Cloud Firestore triggers, let us create the Realtime database triggers, so Realtime Database triggers. And for Realtime database triggers, the Firebase SDK provides the functions.database object. So let us start by creating the first function. For that, write in here exports.addText. So this is the name of the function, and for this function to be defined or to be used as an event handler, we are going to write functions.database and then create a reference to the database. Now the reference to our database is going to be texts/ any text, so I’ll just write in here textId. Now next, we need to define the event time. So for that, we write onCreate. This will have two parameters, and then in here, we are going to define the snapshot and the context. Now for the moment, let us just console.log just an info, so those two, and then in here open curly brackets and write console.log and then text was added so text was added. And then we can do the same for the other event handlers. So we define the onCreate. Let us define the updated event handler, so for that, we write onUpdate, then change the name to updateText and then text was updated. Then let us do the same for the delete, so I’ll just copy the text and paste it down here, change the name to deleteText and then onDelete, Text was deleted. And the last one is going to be onWrite, which is triggered whenever something happens in a document. So I’ll just copy these lines and then paste them down here, change the name to changeText, and then let us be more specific for the text. So let us define a name for the path in here. So texts and then /mytext, then change the onDelete to onWrite and mytext was changed. So we created all the realtime database trigger functions, now let us publish all these functions to our Firebase project. For that, write Firebase deploy –only then functions:addText and do the same for the other functions as well. And then press Enter. So here, we see that we get a cannot read property ref of undefined and that’s right because instead of data, we need to write database, and then change the value for the other functions as well. Save the changes and publish the functions one more time. So here we see that all the four functions were published successfully.

Handling Realtime Database Event Data

On the last part, we created some triggers for the Firebase realtime database. Now let us see how we can trigger these functions and how we can handle therealtime database event data. First of all, let us go to the Firebase project. And then in here, click on the Functions menu item, and on the dashboard, you aregoing to see that now we have the new functions. So we have the addText, changeText, deleteText, and the updateText at the bottom. And if you hover over theicon on the right, you are going to see that this function is a database related function. If you go, for example, to the staffChanged, you are going to see thatthis function is a Cloud Firestore related function. Now let us go to the database and trigger these functions, but before, go to the Logs section. From the logs,choose the addText, deleteText, updateText, and the changeText functions and click the Done button. Then next, right-click on the Database menu item andopen it in a new tab. From the two options in here, choose the Realtime Database, and then next, over the project name, add a child. We are going to name this one texts and we are going to add our first text. The name of the first text is going to be sms, and then inside the sms, add value, and then in the Value section write Hello from Realtime Database. And then press Enter for these changes to be saved. So the changes were saved. Now let us go back to the Functions. So in here, we see that the addText method is being executed. If we go back to the database one more time and delete this text and then go back to the logs, wait for a couple of seconds, maybe up to 10 seconds, so in here we gather results. It says that the text was deleted. Now in Visual Code, let us see how we can handle the changes from here. So in here, go inside the updateText function. The first thing that we need to do is that we need to catch the value that was changed, and then change this value to uppercase, and after we have changed it to uppercase, we need to store it back. So let us first get the value and change it to uppercase. For that, we write in here const uppercase is equal to snapshot.after the changes were made and then get all the values. From all the values, I want to get the value property and then change this value to uppercase and that’s all. Now that we have the data, we can send it back. So for that, we write return snapshot.after, create a reference, and then inside this reference, create a child, name this child property uppercase, and then set the value to be uppercase. Let us save the changes and publish this function. So for that, in our terminal we write firebase deploy –only and then functions: and then the name of the function which is updateText, so updateText, and press Enter. We see that the function was updated successfully. Now let us go back to the Firebase console, and in Firebase console, let us create it one more time. So we write in here texts, and inside texts, we are going to create just a test, and then inside here, we are going to define the properties. So I’ll write value and this is a value. And then press Enter for the changes to be saved. Now the event handler, in our case, is in the update. So far, we should not expect any result, but if we change the values, so in this case, we are going to trigger the onUpdate event handler, we should see the uppercase property in here. So let me just change it to update it and then press Enter and here we are going to see the additional property uppercase. So if I change this value again to just asd, here we are going to see the uppercase, and you can change the value property in here toanything. You are going to see that the uppercase, it is going to change to the latest value.

Working with Firebase Authentication

You can trigger a Firebase function in your response to the creation and deletion of user accounts via Firebase authentication. For example, you can send a welcome email to the users that just signed up. Or you can send a goodbye email to the users that just deleted their accounts. But which are some of the usercreation events in Firebase functions. Firebase accounts will trigger user creation events for cloud functions when user creates an email account and passwordor when a user signs in for the first time, but using a federated identity provider. Also, an event is triggered when the developer creates an account using theFirebase admin SDK or when a user signs into a new anonymous authentication session for the first time. It is important to know that a cloud functions event is not triggered when a user signs in using a custom token. So now let us go to the Visual Code project and create some triggers to work with Firebaseauthentication. In the top of index.js file, create a new section for the authentication triggers. So in here, write Authentication triggers. The first thing, as always, is going to be the creation of the functions. So let us create two functions in here by writing exports. the function name, which is going to besendWelcomeEmail, and then in here, write = functions.auth, which stands for authentication, and then .user. So we are going to handle all the user relatedevents. The first one that we are going to define is going to be onCreate, so when a user is created, and then inside brackets, write user. We are just going toconsole.log the user information, but you can normally use this user data to send an email to the user. And to send an email, you just need to get the email. So for example, const email is equal to user.email. And then next, let us just write console.info New user and let us just display the user or change this from New user to be New user created. Let us do the same for another event, so I’ll just copy these lines of code and then paste them down here. Instead of send a welcome email is going to be sendByEmail so when the user deletes their account. And then the event is going to be onDelete. Let us remove this line of code and change the info to User deleted and we can remove this user from here. Let us save the changes and publish these functions to our Firebase project. So for that, we’ll write firebase deploy –only and then functions: will define the first functions so WelcomeEmail and then, functions define the second one, which is sendByeEmail, and then press Enter. So we see that the functions were published successfully. Now let us go through the Firebase console. If you go to the Dashboard tab from the Functions menu item, you’re going to see that now in here we have two new functions. We have the sendByeEmail and the sendWelcomeEmail. In here, let us go to the Logs tab, and then from the All Functions drop-down, choose the ones that we just created. So the sendBye and the sendWelcomeEmail, and then click the Done button. We see that currently don’t have any events, but let us trigger some of them. So go to the Authentication tab, and to add a user in here, we need to first set up the sign-in method, so for that, click the Set up sign-in method button, click over to the Email/Password, and then Enable, and then the Save button. So the email and password were enabled. Now let us go back to the Users tab, and in here, let us create a user. I’ll provide an email and then just a password, and then click the Add user button. Let us create another user and then define a password and I click the Add user button one more time. So now we have two users. Let us go to our Functions logs and here we see that we get some results. So for example, we see that New user was created, which is the second one, but we also get a message for the other user too. When you scroll down, you are going to see that the other user was created too. Let us go back to authentication one more time and delete the user. So I’ll just delete the first one, delete account, and then click the Delete button. So the user was deleted. If I go back to the functions and wait for a couple of seconds, maybe up to 10 seconds, and in here, we are going to see the user deleted message.

Triggers on Cloud Storage Changes

You can trigger a Firebase function in response to uploading, updating, or deleting of files and folders in Cloud storage. To create a function that handles the cloud storage events, we can use the functions.storage. And Cloud storage supports different events. It supports the event onArchive and this event is onlysent when a bucket has enabled the object versioning. Also, it supports the onDelete and it is sent when an object has been deleted permanently. Another event that Cloud storage supports is the onFinalize and this event is triggered when a new object is successfully created in the bucket. And the last one is theonMetadataUpdate and this is sent when the metadata of an existing object changes. So now let us see in action how we can create different functions for these event handlers. And for that, let us go to our Visual Code project. On the index.js file, at the top of this file, let us create a new section and we are going to name this section the Cloud storage triggers. So here let use start with the first one, the onArchive. For that, we need to create a function. So we write in here exports.onArchive is equal to functions and we set it for the cloud storage we can use the functions.storage, storage, and then object, then we define the event handler onArchive. This is going to respond with an archiving object, so for that, we write object and then here it goes too. Now in here, we are not going to implement the complex logic because that is not the intention of this course. So I’ll just write in here console.info and then we can just display in here theonArchive storage. Let us do the same for the other handler, so for that, I’ll just copy the Line 6 to 8, paste it down here, and change the onArchive to onDelete, then we change the handler to be onDelete, then we change the text as well to be onDelete storage. Let us do the same for the onFinalize, so I paste it in here, then I change the function name to be onFinalize, then we change the handler to be onFinalize and then the text as well to be onFinalize storage. And there is one more left, the onMetadataUpdate. So let us change the function name first to onMetadataUpdate and then the handler as well to be onMetadataUpdate and let us change the text too. So we created four new functions, let us deploy these functions. For that, we write firebase deploy –only and then functions:onArchive and we do the same for the other functions as well. And then press Enter. We’ve seen here that from four functions, the onDelete function and onFinalize function were not deployed successfully. So let us deploy these functions one more time. For that, write in here firebase deploy –only and then define the onDelete and the onFinalize functions, and then press Enter and wait for a couple of seconds. Now that these functions were deployed successfully, let us go to the Firebase console and see these functions in action. So if you go to the Functions and then Dashboard tab, here you are going to see the four new functions that we just created. So we have in here onArchive, onDelete, onFinalize, and onMetadataUpdate function. If you hover on the icon on the right, you’re going to see that this function is a cloud storage related function. Now let us go to the Storage menu item and trigger these functions, but before we trigger the functions, let us go to the Logs tab, and from all functions in here, choose the newly created functions, so onArchive, onDelete, onFinalize, andonMetadataUpdate. Then from the log levels, let us choose the Info, and now let’s go to the cloud storage. In here, let us upload a file, so I’ll just upload an image. So now we expect the onFinalize event handler to be triggered. Let us go to the Log section, in here, you’re going to see that onFinalize storage is in here. Let us go back to the storage. In here, click over to the image and then scroll down to the file location and click in here the Create new download URL. So this will basically change the metadata of our item. Let us go back to the logs and wait for maybe up to 10 seconds. In here, you are going to see that the function onMetadataUpdate was triggered. Let us go back to the storage one more time and delete this item. So for that, select the item and then click the Delete button, confirm it, and go back to the logs, and we see that onDelete function was triggered.

Accessing Storage Object Attributes

When working with cloud functions and cloud storage, the cloud functions will expose a number of storage object attributes such as size and content type for the file that we update or for the files that we upload. And on this part, we are going to learn which are the main object attributes and how we can see all of them. So if we need them in the future, we can use them. So let us see how we can access the storage object attributes in action, and for that, let us go to theVisual Code project. In your index.js file, go to the onFinalize function. And inside here, we are going to read some of the properties of the object that we get in return when we upload a new file. So let us start with the fileBucket, for example, because we want to know where the file is stored. For that, we write constfileBucket is equal to object.bucket. If you want to get the file name or the file path, then you can just write const filePath is equal to object.name, and if you want to get the content type, you can simply write some Content-Type and then change the object.name to object.contentType. Now let us display these values to the users. So for that, we write console.info and then we create three of them. So we display first the fileBucket, so fileBucket - and then we display the value of the fileBucket. We do the same for the filePath and the ContentType. And if you want to see all the properties of an object, you can write in here console.log and then just object - and then simply display the object. Then I’ll say the JSON deployed this function, so for that, we write firebase deploy –only, and then from the functions, we just define the onFinalize. So the function was deployed successfully. Now let us go back to the Firebase console in the Storage menu item. Let us upload a file. So I’ll just choose an image, and once you upload the image, you are going to see that it is a png image file. Now let us go to the Firebase functions. In the logs, you are going to see that for the image that we just uploaded the fileBucket is the project ID .appspot .com. Then we have the filePath to be the name of the file, the content type is png image, and then here we can see which are all the properties of the object. So here we have the bucket, we have the contentDisposition, and much more.

Summary

On this module, we talked about triggering and handling event data and we talked about different Firebase services. We started with the Cloud Firestore where we talked about how to create event handlers and how to handle the data that come as a response. And if you want to learn more about Cloud Firestore, you can check out my course, Firebase Firestore: Getting Started. After Cloud Firestore, we talked about realtime database. We saw how we can trigger an event and how we can send a response back to the realtime database and store the data there. Then next, we talked about Firebase authentication and how to set up triggers when we create or delete a user. And then at the end of this module, we talked about cloud storage. We talked about how we can trigger an event when we upload a file, when we modify a file, or when we delete the file. We also saw which were the main object properties that we get as a response when we trigger a cloud storage event. So I hope you have had as much fun watching this course so far as I have had creating this, so see you on the next one.

Writing Firebase Functions

Introduction

Hi, and welcome to this module where we are going to talk about writing Firebase functions. We are going to start this module by first talking about managingfunctions. We are going to talk about deploying functions, deleting functions, and modifying them, like for example, the function name, the region, or the function trigger. Next, we are going to talk about writing functions in TypeScript. So far, we have written our functions using JavaScript. On this part, we are going to see how we can use TypeScript instead of JavaScript to write functions. Then next, we are going to talk about simplifying asynchronous functions. We are going to see how promises work and much more. Then next, we are going to talk about retrying asynchronous functions, and at the end, we are going to talk about some tips and tricks.

Managing Functions

On this part, we are going to talk about managing functions in Firebase. So we are going to start by first learning how to publish a function, and then next, we are going to see how we can delete a function, how we can modify a function, and then how we can set up the runtime options. So let us start with the first one. Now we have seen so far how we can publish a function. We have said that if you want to publish all the functions, we can simply use the firebase deploy –only functions. This means that we are going to publish all the functions. If we don’t want to publish all the functions, we can choose the specific functions that we want to publish. For that, all we have to do is that we need to define the function’s names. So in this case, let us say we have two functions, the firstFN and the secondFN. To publish only these two functions, we write functions, then colon, and then firstFN, we’ll define the second one. It is important to not have any space between the firstFN and the functions keyword. Since we have already seen how to publish functions, let us start with the deleting functions. We can delete functions in a Firebase project using two ways. We can either remove the functions from the index.js file and then deploy all the functions or we can use the Firebase CLI. Let us see the first way. So from the index.js file, let us remove all the cloud storage triggers. I will select all of them and then delete. Save the file, open the terminal, and then type the Firebase deployed command, and once we press Enter, we are going to see that we are being asked if we want to delete these four functions. And if you want to delete these functions, you need to type Y in here, which stands for yes or you can just press Enter to ignore this message. We are going to delete this function, so for that, we typically Y and then press Enter. So we see that all the functions were deleted successfully. Let us go through the Firebase console and see the result. If we go to the Firebase console in the Functions menu item, we are going to see that the functions that we just deleted do not exist anymore. So this is how you can delete the functions by removing them from the index.js file prior to deployment. Now if you want to delete a function using the Firebase CLI, for that, in your terminal, write Firebase, and then functions:delete. If you want to delete all the functions that mention the specified name in all the regions, you can just write in here the function name. So for example, I will just write in here updateText. And if you want to delete more than one function, you can simply put a space and then define the second function. And to delete functions that belong to a certain region, you can just define the region here, region, and then us-central1 and then simply press Enter. So we are deleting two functions, the delete text and the object text from the us-central region. Let us type y and then press Enter. So we see that the two functions were deleted successfully. Other than deploying a function or deleting afunction, it is possible to change the function details. We are going to see on this part how to change the functions region, but you can change the same waythe function name or the function trigger and the steps that you need to follow are the same. So first, we need to create a new function with different details. Then next, you need to deploy the newly created function, and at the end, you need to delete the previous function. It’s important to know that for functions we have four different regions. The first one is the us-central, the second 1 is the us-east1, the third 1 is the europe-west1, and the last 1 is the asia-northeast. Letus see in action how we can change our function details. In our index.js file, let us change our date function. Copy this function and then paste it down here.First step, let us make all the necessary changes in our function and let us start with name. Let us define the date to be dateNew. Then to change the region, after the https write .region and here we need to define the new region. Let us define the new region to be the Europe-west1, so let me write europe and then -west1. If you want to change the functions trigger, you can do that by just replacing the onRequest with onCall, but we are not going to change the functions trigger for this function. So now here we have the same function with different name and different specifications. Next, let us save all the changes and deploy this function. For that, go to the terminal, and in here, write Firebase deploy –only functions and then define the function name to be dateNew. So in here, now we see that we get an error and the error says that functions.https .region is not a function and that’s right because instead of defining the region after the HTTPS, we need to define the region after the functions. So let us remove that from after the HTTPS and put it in here. Save the changes and publish the function one more time. Now that the function was deployed successfully, we need to remove the old one. So for that, we write in here firebase functions:delete and then we define the function name to be the date function. Confirm this action by typing y and then pressing Enter. So we see that the function was deleted successfully. Now let us go to the Firebase console. If we go to the Firebase console, here we have the date function. Let us refresh the browser, and here we see that instead of the date function, we have the function dateNew and we see that the region is set to be the europe-west. Before we proceed to the next part, let us see how we can define some runtime options, like for example, the timeout. For that, go to the sendWelcomeEmail function, and after the functions, write .runWith. Inside here, we can define all the runtime options, like for example, we can define a timeout, so for that, let us write in here timeoutSeconds and let us set the timeoutSeconds to be 300. Now for this change to be saved, you need to deploy the sendWelcomeEmail and this is how you can manage the Firebase functions from the Firebase CLI.

Writing Functions in Typescript

On this part, we are going to see how we can use TypeScript in a cloud functions project. We are going to first see how we can initialize a cloud functions project with TypeScript, and then next, we are going to see how we can migrate an existing JavaScript project to TypeScript. But why should we use TypeScript instead of JavaScript? TypeScript supports the latest JavaScript features, like for example, the async await simplifying the promise management. Also, a cloud functions linter highlights the common problems while you are coding, and of course, TypeScript supports type safety. Type safety helps us avoid runtime errors in deployed functions. So let us first see how we can initialize a new cloud functions project with TypeScript. To create a new cloud functions project, create a new directory, and then inside that directory, write firebase init command. And then from the options in here, go to the functions, press the Space bar to select the functions. Then next, press Enter. From the project list, choose a project, and then between the JavaScript and TypeScript, select the TypeScript. Press Enter to use the TSLint. Press Enter one more time to install the dependencies. So now that everything was installed, if you go to the functions folder, inside the source folder, you are going to see the index.ts file and this is a TypeScript file, which we can use to write TypeScript functions. And if you go to the package.json file, here you are going to see multiple scripts configured by default, like for example, the serve script, the shell script, the start, etc. Let us navigate inside the functions folder, so for that, we write cd functions, which stands for change directory, and then inside here, write npm run build. Our command will create a new folder, which is the lib folder, and inside this folder, we are going to see the index.js file. So this command is used to basically convert the index.ts file into an index.js file. If we go to the index.ts file and we uncommand this function, then we save the changes and we run the command one more time and we go back to the index.js, here we are going to see the JavaScript version of our TypeScript function. So this is how you can create a new cloud functions project. Now let us go to an existing JavaScript function and see how we can convert it to a TypeScript one. Here we are going to use the project that we used on the last part and you can find this project in your exercise files. In the project directory, run the Firebase init functions command, so firebase init functions. Then to proceed, press Enter, and when asked which language you want to use to write functions, choose TypeScript, and then press Enter. Press Enter one more time. Here, you are being asked if you want to override the package.json file and we don’t want to override this file, so we are going to press Enter. So now we see that three new files were created, the tslint file, the tsconfig, and the index.ts file inside the source folder. Next, let us go to the tsconfig.json file, and in here, let us set the compiler options to allow JavaScript. So for that, write in here allowJs to true. Now let us go to the package.json file, and in here, let us set the main. So for that, write in here main and then define the main to be lib folder, and then inside this folder, we want to have the index.js file, which is going to be as the file that we used to translate our TypeScript code to JavaScript. Next, let us define the build section. So for that, we write in here build and then we paste these commands. Now you can find this command in your exercise files as well. Before we test our application, we need to add the TypeScript and TSLint as development dependencies. Let us first navigate inside the functions folder, so write in here cd functions and then write npm install –save-dev, which stands for development, typescript. Let us do the same for the TSLint, so I’ll simply write in here tslint. If we now go to thepackage.json file, inside here, we are going to see a new section named devDependencies. Now let us run in here the npm run and then the build command. Weare going to see that this command is going to create a new folder named lib, and inside the lib folder, we are going to see the index.js file, which is used as aplaceholder to translate all the TypeScript files to JavaScript ones. So if we go to the index.ts file and remove the comments from this function and we run thesame command one more time, in our index.js file, we are going to see our function. So now you can get all your index.js functions and translate them to TypeScript functions.

Simplifying Asynchronous Functions

When working with the Firebase functions, it is important to manage the lifecycle of a function just to make sure it resolves properly. When working with functions, you need to know how to terminate them and the function needs to be terminated only when all the work is done. But how can we terminate different types of cloud functions. When we have an HTTP trigger function, they are all terminated after you send the response at the end. And when you work with background trigger functions, then you can terminate them by returning a promise, and the promise represents some asynchronous work that should eventually complete. A promise has three states. When a promise is being processed, then it is in the pending state. And from the pending state, we have two possible outcomes. It can be fulfilled, which is when the work completes successfully, of if there is an error, the promise becomes rejected. Now let us see in action how we can create a function and handle all these states properly. I’m going to use the new application project that we created on the last part and you can get the same project from the exercise files. To create a function in TypeScript, I’m going to write export, then const, and then I’m going to name this function getStudent. This function is going to be an HTTPS function, which is going to be executed on request. And in here, we pass two parameters, therequest and the response right in here it goes to. And then inside the curly brackets, we are going to write all the code. Now in here, we are going to interact with the Cloud Firestore. So for that, let us import the Firebase admin. So write in here import all as admin from the Firebase admin and then initialize it bywriting admin.initializeApp. Now let us go inside the getStudent method, and in here, write admin.firestore to create a reference to the firestore.doc, whichstands for document because we want to create a reference to a document in the firestore. The document is going to be within the students collection, and then the document name is going to be etrupja. You can name your document whatever you want because you are going to create the document later. So whenever we trigger a get request on this document, we are going to get response. It will be either a success or a failure. And whenever the request is successful, we want to get the result. So for that, we write in here .then and then let us get the response of this request. So for that, we write snapshot that it goes to. Now that we have the result, we can terminate this function successfully. So for that, we write in here response.send and we want to send a response in the JSON format, so for that, we write snapshot.data. But what if something goes wrong with our function, so if an error is thrown or the connection doesn’t work. In this case, we want to catch an error and then send the response to terminate our function. So for that, we write in here .catch and then in here error that goes to. Let us terminate the function the same way, so response.status 500 .send Something went wrong! This is all you have to do in here. Now let us goto Firebase console and create this document. Inside your project, go to the Database menu item and then choose Firestore. Inside the Firestore, let us add a new collection named students, then click Next, provide the document ID to be etrupja or your document id and then add a field in here, for example, FirstName of type string. Let us add one more, put in LastName and press the Save button. So now we have the collection, we have the document, and we have the document fields. Let us go back to the Visual Code. To run the functions locally, write in here firebase serve. So we see that the functions were started successfully. Let us copy this link, go to any browser of your choice, paste the URL in here and then press Enter. So in here, we are going to see the results of this document in JSON format.

Retrying Asynchronous Functions

On this part, we are going to see how we can request the asynchronous background functions to retry on failure. By default, without the retries enabled, a function will either succeed or fail in the first try. So this means that the function is going to executed only one time. And when a function is executed only one time, the success is not guaranteed. When you enable the retries on a background function, however, the semantic change to at least once, which means that the function is going to be executed until it is executed at least one time successfully. But which are some of the main reasons why functions fail? One of the main reasons is that the function has a bug and the bug may cause a function to fail. Another reason would be when the function cannot reach an endpoint. So for example, you ask for a document which does not exist. Another case would be when you intentionally throw an exception or when you return a rejectedpromise. Now let us see in action how we can enable retry in asynchronous functions. For that, let us go to the console.cloud .google .com. In your URL, write console.cloud .google .com. Then from the drop-down in here, choose your project. So go to the All tab and then choose your project. Then from the menu onthe left, scroll down to the Cloud Functions. Click this menu item, and in here, you see all the functions, and in here, let us choose the function, but you need to make sure that the Trigger field is set to a background function trigger type, so just for example, cloud storage. So let us scroll down in here and let us choose the staffDeleted function. Click on this function, and then click the Edit button, then scroll down to the More button, click this button here, then scroll down to the bottom of this page. Then check the Retry on failure checkbox. And then next, save the changes for this function. So this is how you can enable the retry on failure in an asynchronous background function.

Tips and Tricks

On this part, we are going to talk about the best practices for designing, implementing, testing, and deploying cloud functions. We are going to first starttalking about the best practices for designing and implementing cloud functions. Then next, we are going to talk about tools to implement, to test, and tointeract with cloud functions. And then at the end, we are going to talk about which are the best practices for optimizing performance. So let us start with thefirst one, which is correctness. Now when writing Firebase functions, you need to make sure that you write idempotent functions, which means that your function should produce the same result, even though they are called multiple times. You should also always delete the temporary files because the local disk storage in the temporary directory is an in-memory file system and failing to delete these temporary files may eventually lead to an out-of-memory error. Before you deploy your functions to your Firebase project, it’s important to make sure that your functions work as expected. So for that, before you deploy them, create a local development environment and test them and you can test the Firebase functions locally by using different libraries. And we are going to see on the next part how we can test our Firebase functions locally before we deploy them to Firebase project. Cloud functions does not allow the outbound connections on port 25, so this means that we cannot create non-secure connections to an SMTP Server. If you want to send emails from your Firebase project,then you can use the Sendgrid and you can find more information about this tool by going to sendgrid.com. Because functions are status, the execution environment is often initialized from scratch, and if your function imports modules, then these modules will add some latency to your function. You can reduce this latency, as well as the time needed to deploy your function by loading the dependencies correctly and not loading the ones that you don’t use. Also, if you want to reuse objects throughout your application, you can use the global variables, but when you use global variables, make sure that you use lazy initialization. If you initialize variables in global scope, the initialization code will always be executed increasing your functions latency. So this means that if some objects are not used in all code paths, then consider initializing them lazily on demand.

Summary

We started this module by talking about managing functions, and on this part, we talked about renaming a function changing the functions region and changing the functions trigger type. Then next, we talked about writing functions in TypeScript. We started by configuring TypeScript in a new NT Firebase functions project. And then later, we learned how to migrate an existing JavaScript project to TypeScript. Next, we learned how to work with asynchronous functions. So we learned how to simplify these functions and how to configure the retry on failure. Then next, we learned about some tips and tricks,correctness, tools, and performance when it comes to Firebase functions.

Testing Firebase Functions

Introduction

Hi, and welcome to this module where we are going to talk about testing Firebase functions. But what are we going to learn on this module? We are going to see how we can run functions locally by using the command line and the Cloud Functions shell. Then next, we are going to learn about unit testing functions. We will start with setting up the testing environment, then next, we are going to see how we can test the non-HTTP functions, and at the end, how to test the HTTP functions. So let’s get started.

Running Functions Locally

Before we deploy our functions to Firebase hosting, it is a best practice to run the functions locally and test if everything works as expected. And to test functions locally, we can either use Cloud Functions shell or we can use the Firebase CLI. With Firebase CLI, we can test only the HTTP functions, but with Cloud Functions shell, we can test all kind of functions. So we can test the HTTP functions and we can test the trigger functions as well. To run functions locally, we can use the firebase serve command. But let us go to our project and see how we can run functions locally in action. During this module, we are going to use a new project, which you can find in your exercise files. Inside this project, you can find two functions, the addToDoItem function and the toUpperCase function. The first function is an HTTP function because by using an HTTP function, we can add an item to the todoitems reference, and the other one is a non-HTTP function because it’s just a database trigger which gets triggered when we create a new item in the todoitems reference. Now we said that to run all theHTTP functions locally, we can use the firebase serve command. So for that in your terminal, write firebase serve. So in here, we are going to see only theaddTodoItem function, which is an HTTP function. We can also run the Firebase functions locally by using the Cloud Functions shell. So for that, we writefirebase functions and then :shell. Press Enter, and in here, we’re going to see all the functions that you have within the index.js file. Let us test the realtimedatabase function, which is the toUpperCase function and to invoke a realtime database function, you can just write in here the name of the function sotoUpperCase and then provide a parameter. So I’ll just write in here first task. Let us press Enter and you’re going to get feedback so successfully invoke thefunction. Then you are going to get this log result, which is this one in here and then execution time. Let us go to our database. In our database, we are going tosee that a todoitems reference was created, and inside here, we have a pushId7 and then the uppercase is First Task. So the text that we entered wasimmediately converted to uppercase and stored to an uppercase field. Let us test this function again. So let us write in here second task, so second task and press Enter. We are going to see a second task in here. Let us test it again, third task, and you’re going to see in here the third task. So this is all for this part. On the next one, we are going to talk about setting up the testing environment.

Setting up Testing Environment

On the last part, we learned how to run functions locally by using the Firebase CLI and the Cloud Functions shell. On this part, we are going to learn how to set up testing environment for Firebase functions. So let’s get started. To get started with the Firebase functions testing, we are going to install both the Firebase functions test and the Mocha, which is a testing framework. For that, let us navigate inside the functions folder. So write in here, cd functions, which stands for change directory to functions. Now to install the Firebase functions test, we are going to write npm install, then –save-dev, which stands for development, firebase-functions-test. The first library was installed. Now let us install the Mocha framework. So for that, we write mocha and then press Enter. So the packages were installed successfully. Now let us go to the package.json file, and in this file, we are going to see that we have a separate section, the sectiondevDependencies, and inside this section, we have the firebase-functions-test and the Mocha framework. Now scroll up to the Scripts section. Inside this section, we are going to define a new command for testing. And to define a new command, we need to write in here test, this is a name of the command, and then mocha –reporter spec. Next, we need to create a test folder inside the functions folder. So go to the functions folder, click the create new folder icon, and then name this folder test. Inside this file, we are going to add a JavaScript File, let us name this file index.test .js, and this is a file that we are going to use to write unit tests. And to run the unit tests that we are going to define in this file, we are going to use the command that we defined in the package.json file, which is the npm run test. Let us test this. For that, in the terminal write npm run and then test. And in here, we see that we get an error which says that it cannot find the package.json file and that’s right because we are running this command from within the staff project test folder, but we need to run this command from within the functions folder. So let us go to the functions folder by typing cd functions and then execute the command one more time, so npm run test, and then press Enter. So in here, we see that 0 is passing and that’s right because we have not defined any function in the index.ts .js file. There are two ways to use the firebase-functions-test. We can use it on the offline mode or on the online mode. Now when using it on the online mode, it means that we write tests that interact with a Firebase project dedicated to testing. So the database writes or user creates, etc what actually happened, but not in your real project so you don’t mess up with the real data. And the offline mode is used when you want to write offline unit test with no side effects. So this means that any method calls that interact with a Firebase product, for example, writing to a database or creating a user, needs to be stopped. Now before we go to the next part, let us see how we can initialize the SDK in offline and online mode. To initialize the SDK in offline mode, you simply need to write at the testing file const test is equal to require, and in the require method, define the Firebase-functions-test. But when initializing the SDK in online mode, we need to pass some parameters to this requirement and the first one is going to be the project configuration. So let us write in here const config is equal to, pop on the curly bracket, and go to your Firebase project. Then in here, go to the project overview, and then next, click the Add to the web application button. Copy the values within the config and go back to your project. Paste the values in here and keep only the database URL, the projectId, and the storage bucket. Now we need to pass the config as a parameter in the requirement. So for that, write in here config. The second parameter is going to be a key. To get this key, go to theconsole.cloud .google .com /iam- admin/serviceaccount and then press Enter. And then in here, select the first option which says app engine default serviceaccount. On the actions on the right, click the three dots and then Create key. From the key type, choose the JSON type and then click the Create button. So we see that the JSON file was downloaded and this is what you can find inside this JSON file. Let us copy this content and go back to our application. Inside the functions folder, let us create a new file named account key, so write in here accountKey.json, and then paste the content in here. Save the changes and then go back to your testing file. The second parameter is going to be passed as a reference to this file. So for that, we write in here, inside single quotes,.accountKey .json. Save the changes and this is how you can initialize the SDK in offline and online mode.

Testing Background (Non-HTTP) Functions

Now that we have set up the testing environment, we are ready to test our functions and we are going to start testing by testing a background non-HTTPfunction. The process for testing non-HTTP functions goes through a couple of steps. So first, we need to wrap the function that we would like to test by using the test.wrap method. Then next, we need to construct some testing data. Then next, we need to invoke the wrap function with the test data that we constructed for any event or for any change that we would like to specify. And then at the end of this process, we need to check the result. So we need to make assertions about the behavior. So let’s get started with the first function and see how we can test background non-HTTP function. In our functions file, which is the index.js file, we have two functions. So we have an HTTPS function and the non-HTTP function. So we are going to start with the toUpperCase function. For that, let us go to the index.ts .js file. Before we start implementing the test case, we need to first import all the functions so then we can wrap up the function and test it. For that, let us write in here const myFunctions is equal to require, and then in here, define the path to your functions file, so.. / index.js, in this case. Now next, we need to import two more libraries, the sinon library and the chai one. The sinon library is used to stop the methods and the chai is used for assertions. So let us go to the terminal, do these names, go inside the functions folder, and then in here, write npm install –save-dev and then define the name to be chai. We do the same for the sinon, so we write in here sinon, press Enter. So the packages were installed successfully. Now let us use theselibraries. For that, write in here const sinon is equal to require and then sinon. Do the same for the chai. So for that, write in here chai and then require chai, but out of chai, let us create an assert. So const assert is equal is to chai.assert. So that’s all you need to do to now start writing your function. We said that we are going to test a non-HTTPS function, so for that, let us start creating this function. Write in here describe, and then the first parameter is going to be the title of this function so toUpperCase. And now we need to start implementing this function. So goes to, no need to pass any parameters, and then we need to define what this function should do. Now in here, let us define the specification of this test case. So for that, we write it, what should it do, it should upper case the input and write it to the uppercase reference. Again, we don’t need to pass any parameters. So we just write goes to and now here we start implementing the body of our unit test. Let us define the chai parameter. So const, which is going to be used as the reference where to start this data so childParam is going to be the uppercase node. Then next, we need to define the set parameter, which is like the result that we expect from this test case. So const setParam is equal to INPUT in uppercase. Then next, let us define the stubs. So let us define a child stub and a set stub. So const childStub is equal to sinon.stub and we do the same for the setStub so just change the childStub to be setStub. Now let us create next a snap of data. So let us write in here const snap is equal to, and then inside this called log, define a value and a reference. So the value that we want to provide needs to be the input in lowercase because the result that we are expecting from this test case is the input in uppercase. Next, we need to define the reference. To define the reference, we need to define the parent, and inside the parent, we need to define the child, and the child is going to be the childStub. Now next, let us use these stubs to provide some arguments and what they return. After the snap, write in here childStub with arguments and the argument is going to be the child parameter. It returns the setStub. Let us do the samefor the setStub, so in here, we write setStub.withArgs, then pass as an argument the setParam which returns then a true. And now we need to wrap the function, so for that, we write const wrapped is equal to test.wrap, and in here, we need to define the function that we want to wrap so myFunctions.toUpperCase. Now that we have the data, we have the wrapped function, now we can check the result by using the assert.equal method. So forthat, let us write in here return assert.equal and we want to check the wrapped function, so wrapped, and as a parameter, we pass the snap data and the result should be true. Now to test this function, let us save the changes and go to the terminal. So go to the functions folder, right-click, and then open in terminal. In here, write npm run test. So in here, we are going to see that our function was executed successfully.

Testing HTTP Functions

On the last part, we learned how to test a non-HTTP function, and on this part, we are going to see how we can test the HTTP functions. So for that, let us go to our Visual Code project. So on the last part, we tested the toUpperCase function and this function was tested using stubs, and when you use stubs, it means that you are testing this function offline without interacting with real data on your Firebase project. But on this part, we are going to see how we can write unit tests that interact with the Firebase project. Now normally, you should have a dedicated Firebase project to test your functions, but we are just going to use the same function. Now before we start testing, let us go to the index.js file and the function that we are going to test in here is the addToDoItem function. Now we see that we need to provide a query.text and then we see that a snapshot is created in the todoitems reference where we push the original value, which comes as a query.text parameter. So we see in here that this function, at the end, redirects us by using a 303 code, as a URL, it uses the snapshot reference. As a parameter, it takes a request and a response. Now let us go to the testing file. Inside here, let us start writing our second test. So write in here describe and the title of this test is going to be addToDoItem, then no parameters, so just goes to, and then in here, we define the specification of this function. So this function should return a 303 redirect. And then in here, we define a function name to be done because we want to call this function when we have everything ready. Goes to. Now we need to define all this specification. So let us first define the request and then next the response. For the request, we want to write const request is equal to we want to create a query and this query will have a text parameter named input. So if we go to the index.js file, you are going to seethat we have a request and this request has a query, and inside this query, we have the text property. And now, let us define the response. So for that, we writeconst response is equal to and then we expect a redirect and this has a code and the URL. So the redirect, if we go to the index.js, so the redirect in here has acode and it has a URL. This goes to. Now we need to define the redirect. So first of all, we need to check if the redirection code is 303. For that, we write assert.equal is a code equal to 303. Next, let us define the expected reference, so const expectedRef is equal to new. Let us define a regular expression in here so RegExp and then config.databaseURL. So we are using the config up here, and if you want to work in a testing environment, then you need to change the config in here to your testing environment. So config.databaseURL, and to this databaseURL, we want to add the todoitems, so todoitems because if we go to our function, in here we have the reference to the database, and then to this database, we add the todoitems. Now we need to check if these references areequal. So assert.isTrue, and then in here, write expectedRef.test and then the URL itself. Let us call the function, so done. And then after the response, writemyFunctions.addTodoItem and then pass as a parameter the request and the response. So this is all we have to do for this test. Now let us test this test by going to functions, opening terminal, in here, write npm run test. So now we see in here that both tests are passing, but we said that for this test we are interacting with the Firebase project. Let us see what happens in our Firebase project. So we have opened our project on the left. Let us run the npm run test command one more time and we see that in our database a new item is created. If we go inside this item, we are going to see the original to be input and the uppercase to be INPUT in capital. The first value in lowercase is created by our addToDoItem function, but the second one is created by our Firebase Realtime database trigger, which is the toUpperCase function.

Summary

We started this module by talking about running functions locally. We learned how to run functions locally by using the command line, and by using the CloudFunctions shell. We learned that by using the command line or the Firebase CLI, we can only run the HTTP functions, and if we want to run the other functions, we need to use the Cloud Functions shell. Then next, we learned how to test functions. We started by first setting up the environment, and then next, we learned how to test a non-HTTP function. We did so by not interacting with a Firebase project so we used the offline mode. But to test an HTTP function, we use the online mode. So in here, we interacted with our Firebase project. Thank you for watching, and see you on the next module.

Monitoring Firebase Functions

Introduction

Hi, and welcome to this module where we are going to talk about monitoring Firebase functions. But what are we going to learn on this module? We are going to start this module by talking about writing logs. Logging is an important tool for debugging and monitoring code. And then we are going to see how we can view the logs. Next, we are going to talk about reporting errors. We will learn about different types of reporting and how we can view them from different sources. Then at the end of this module, we are going to talk about viewing monitored metrics. So let’s get started.

Writing and Viewing Logs

Welcome to this part where we are going to talk about writing and viewing logs in Firebase functions. Now logging is an important tool for debugging andmonitoring code and cloud functions gives us the same consult object that we normally use when we develop applications for web. And in cloud functions, we have different logging levels. We have the info log level, the error log level, and the debug log level. When we use the log and info commands, we have the info log level and we normally use these commands when we want to display useful information while our function is being executed. Then next, we use the warn and error commands and we use these commands when we want to display an error while our application is being executed. The last logging level is the debug logging level and all the internal system messages have the debug log level. Let us go to our project and see how we can write and view our logs. For thismodule, we are going to use a project which I have already created and you can get this project from your exercise files. And in here, go to the index.js file andthen inside the helloWorld function. So in here, we are going to use all the five commands, for that, let us start with the first one so console.log. Then we aregoing to use the other one, console.info, then console.warn, console.error, and the last one is the console.debug. Let us enter some meaningful messages for all of them. And to see the changes, we need to publish this function to our Firebase project. So in here, write firebase deploy –only functions and then define thefunction to be helloWorld. So we see that the function was deployed successfully and this is how you can write logs inside a Firebase function. To test this function locally, write in here firebase serve, and then to run this function, copy this link and go to any browser of your choice, paste the link in here, and press Enter. So we see that the function was executed successfully, and by now, all the logs should have been emitted successfully. But how can we see the logs that we just emitted in our function. To view the logs for Firebase functions, there are three ways. We can either use the Firebase CLI, or we can use the Firebase console, or the other option is the Stackdriver logging UI. Let us see all these options in action. Let us start with the Firebase CLI. To view the logs with the Firebase tool, use the functions log command. So for that, write in here firebase functions and then log. This will display all the logs for all the functions within this project. So in here, we see that we have some logs, and if you want to see all the Firebase logs for a specific function, then you need to write firebase function logs, and then by using the only flag, you need to define the functions name. So let us write in here helloWorld. So here we have the result, and if you want to see a full range of the log viewing options, then you can use the help option. So for that, let us write in here firebase help and then functions:log. So in here we see all the available options for the functions log command. So this is how you can see the logs using the Firebase CLI, but we can also view the logs by using the Firebase console. For that, go to your project, then go to the Functions menu item, and then in here, go to the Logs tab. Now in here, we don’t see any results yet because we executed our function locally. If you want to see some results in here, go to the Dashboard tab. In here, copy the link of this function and then paste it in a new tab. So we’ll see that the function is executed successfully. And now, let us go back to the Firebase project. Go to the Logs tab, and here we can see a lot of results. So we can see the this is a log, this is an info, this is a warning, and this is an error. Down here you can see the level column, and in the level column, we can see only three icons. So the flag that you see in here is for debug, the red one is for error. If you want to choose a specific function,you can do that from the All functions dropdown, so helloWorld and then click Done. You can also filter the logging levels. So let us say, for example, we want only the error logging levels, then here we are going to get only the emitted errors in our function. The last way to view the logs is by using the Stackdriverlogging UI. To go to the Stackdriver, go to the console.cloud .google .com, so console.cloud .google .com. Then from the menu on the left, scroll down to theLogging menu item and then choose the Logs. From the projects drop-down, choose our project, so I’ll choose the Monitoring project and here we have all the logs. In here, we also see three icons. So we have the info icon, we have the error icon, and the debug icon. In here, you can also choose the log level. So for example, we can choose to display only the errors. And now in here, we see only the error level logs.

Reporting Errors

On this part, we are going to talk about reporting errors in cloud functions and we can report them automatically or manually. Let us now see in action how we can report errors in cloud functions, and for that, let’s go to our project. For reporting errors, we are going to use the Stackdriver error reporting. You can emitan error from a cloud function to Stackdriver error reporting by using the error object. So for example, let us go to the helloWorld function, and in here, write console.error, and then as a parameter, we need to pass an error object. For that, write new and then Error and then pass a message. So for example, This is a failure. You can also emit errors to Stackdriver by throwing an exception. So for example, throw new Error, and in here, we write a message Another failure. You would normally do this inside a try and catch block, but just for demonstration, we are doing them inside this function. But for example, if you write in here console.info or console.log and then you create an Error object inside here, you can just write in here Any error, for example, in this case, this error is not going to be emitted to Stackdriver, but it is going to be logged as an error object the same way if you throw one, for example, or if you respond, for example, by using a status code of 500, for example. In these cases, you cannot emit an error to Stackdriver, but with the first two lines, you can. Now let us publish this function to see the results. So in here firebase deploy –only functions and then helloWorld. Now that we see that the function was successfully updated, let us go to the browser and execute this function multiple times. So in here, I’ll press Enter. The function was executed one time. Let us execute the function one more time. And you can execute this function as many times as you want. To see the result, you need to go to the console.cloud .google .com, and then on the menu on the left, scroll down to the Error Reporting, click this menu item, then from the drop-down up here, we can choose the projects. I’ll choose theMonitoring. And then here we are going to see all the errors that our cloud function has emitted. Now let us go back to our project and see how we can manually report the errors. Now in here, we are going to write the function, but before we start writing any function, we need to install some dependencies. So for that, let us go inside the functions folder by typing in here cd functions, and then in here, write npm install –save @google-cloud. So the package was installed. Now inside the index.js file, let us import the logging library, so for that, we write const logging is equal to require, and then in here, write google logging. Now we are going to create a function and we are going to use this function to send the errors to our Stackdriver. And a properly formed log entry requires a monitored resource object and an error event object. So let us start creating our function by keeping in mind these two objects. Let us name this function function reportError and we are going to pass as a parameter an error and a context which bifold is going to be empty. Now inside the function body,let us define the log name and the log itself. So write in here const logName is equal to errors and the const log is equal to logging.log the logName. Next, we need to define the metadata, so for that, we write in here const metadata is equal to, inside the metadata, we need to define the resource and the resource has two properties. The first property is the type and this is a cloud function, so for that, we write in here cloud_function and the second property is the labels property. And then inside the labels, we have the function_name property, and the value of the function_name is going to be process.env. the function_name. So in our case, if we execute it from the helloWorld function, it’s going to be the helloWorld function. So we write in here FUNCTION_NAME. Next, we need to define the error event. So we said that we need to define the monitored resources and the error event. Let us write in here const errorEvent. This is equal to, and then inside here, define the message, which is going to be error.stack or we can change the parameter to be just error just so we know with what we are working. So error in here .stack and then service context. The second property is the resourceType and the resourceType value is the cloud_function. Let us add the column in here and then change the type up here to function and that’s all. Another property for the error event is the context and the context is going to be the same as the context parameter. That’s also now we have everything we need to return a new promise which is used to write the error log entry. So in here, let us write return new Promise. As a parameter, we write in here resolve and reject goes to. Inside here, we write log.write log.entry, we pass twoparameters for the log.entry. The first one we said is the monitored resource and the second one is the errorEvent, so metadata, errorEvent, and then in here we write error that goes to and we check if is an error, then we want to return a reject with the parameter the error itself, otherwise, we want to return theresult, so return resolve. And this is all we need to do to write this function. Now if you want to use this method, simply go inside the function, and then inside this function, write return reportError and pass as a parameter an error and a context. For example, new Error, and then I’ll just write in here This is the function and I’ll leave the context to be nothing. Remove these two lines. And then next, save the changes, publish your function, execute the function, and then go to the Stackdriver. And in the Error Reporting, we are going to get the error that we just created. So here, you can see the report error method.

Viewing Monitored Metrics

On this part, we are going to see how we can use the Firebase console and the cloud platform console to view the metrics of our Firebase functions. In Firebase console, go to the Functions menu item, and in this menu item, we are going to see four main tabs. So we have the Dashboard tab, and in here, we can see all the functions. We can see the function name, the function trigger, the region of the function, the Node.js runtime, the memory allocated, and the timeout. The next tab is the Health tab, and inside this tab, we can either get information for all the functions or from the drop-down, we can choose only one function. In here, I’ll choose the helloWorld function. If you scroll down here, you are going to see a graphic for all the errors that this function has emitted. And then next, we are going to see the error groups, and in the error groups, we are going to see the number of errors for each type of error. So for example, for the Error object, we have in here eight counts, which means that this error has happened eight times in the helloWorld function. If you scroll down, you are going to see the performance, the latency, and the memory for this function. And then at the end, we are going to see the outbound networking. If you want to find out more about the single function or more than one function, you can go to the Logs tab. Now we have seen this tab so far, so I’ll just go to the last one which is the Usage tab. And in the Usage tab, we can see the number of invocations, which is the total function invocation number. So in our case, it’s eight, and this is pretty much all the information that you can get using the Firebase console. If you want to learn about more metrics about Firebase functions, you can go to the Cloud Platform console. So for that, go to the console.cloud .google .com. And then, from the menu on the left, go to the cloud functions, next, choose a function that you want, and then in here we can see the invocations, we can see the execution time, the memory usage. You can also go to the triggers, to the source, or you can see where this function is allocated, and then you can test this function if you want to. Let us go back to the General andscroll down. In here, we can see the last deployed time, we can see the region of the function, we can see the memory allocated for this function, we can seethe timeout, the service account, a list of all the errors in the last 7 days. So for example, the error, another failure, was thrown eight times and you can also see the environment variables if you have specified any.

Summary

We talked on this module about logging in Firebase functions. We started by first seeing how we can write a log and then how we can view the logs. And then at the end, we talked about reporting logs. We learned how to automatically report errors to Stackdriver and how we can create a function to manually report an error to the Stackdriver. By the end of this course, we talked about viewing monitored metrics for the Firebase functions. To view the metrics, we used both Firebase console and the cloud platform console. So this is all for this module. Thank you for watching, and see you on the next one.

Upgrading Firebase Function from Beta Version

Introduction

Hi, and welcome to the last module of this course. On this module, we are going to talk about upgrading Firebase functions from the beta version. And we are going to start this module by first talking about the background non-HTTP functions. We are going to talk about all the changes and much more. Then next, we are going to talk about the SDK changes by the trigger type. We will mention some of the most important triggers of the Firebase services. So we will talk about the Cloud Firestore trigger, about the Realtime Database trigger, and much more. So let’s get started.

Background (Non-HTTP) Functions

We are going to start this module by talking about the SDK changes that affect all the background non-HTTP functions, and the first change is that the eventparameter is split now into the data and context parameters. The data parameter represents the data that triggered the function and the context parameterprovides information about the functions execution. So in here, we have an example function for the database or a Firebase Realtime database trigger. Now we are going to use the context parameter to get different useful information, like for example, the event id, the timestamp, etc. Let us say you want to get theauthentication information for the user. For that, we are going to use the context.auth property. And if you want to get the permissions level for the user, then you need to use the authType. And if you want to get the ID in the path, then you can use the context.parameters, or params, .id. We know that each event inthe background functions has a unique id, and if you want to get this unique event id, then you can use the context.eventid. Then if you want to get the timestamp when this event happened, then you can use the context.timestamp property. And if you want to get the event type, you can use the eventType property. You can also get the resource which triggered the event by using the context.resource property. Compared to beta version, the way that we initialize the Firebase admin has changed as well. So for example, before we used to define the functions, the admin, and then by using the initializeApp method, we hadto provide as a parameter the functions that config.firebase configuration. But now, we can just write admin.initializeApp. So we see that the functions.config .firebase has been removed.

SDK Changes by Trigger Type

For many supported function triggers, version 1.0 has introduced changes in the naming for the data fields and methods. On this part, we are going to talk about some of the SDK changes for some of the triggers. So let us start with the Firebase Realtime database. You can still create the reference for the FirebaseRealtime database the same way. So you basically use the database object and then the ref method to create the reference. But before, for example, on the onWrite method, you would have an event parameter. And then, by using this event parameter, you would get all the necessary data. Now we don’t have one parameter, we have two parameters, we have the change and the context. In the beta version, if you wanted to get the data before change, then you would use the event.data .previous .val methods, but now, you can get the before data by using the change.before .val. In the beta version, if you wanted to get the latest version of the data, then you would use the event.data .val method, but now, you can just write change.after .val, which in my opinion, it is better because of the before and the after keyword. What about the Cloud Firestore? You can still create a reference to a document the same way, but if you are going to use the onWrite method, it used to have only one parameter, but now it has two parameters. And if you wanted to get the before data, you would use the event.data .previous .data method. Now you can just write change.before .data, and in beta version, if you wanted to get the latest data version, then you would use the event.data .data method, but now, we can just write change.after .data. When it comes to authentication, you still can create a reference the same way. But now the onCreate method has two parameters, it has the userRecord and the context. But before, if you wanted to get the created at timestamp, then you would create a userMetadata, and then by using this userMetadata, you would write userMetadata.createdAt, but now, you can just write userRecord.metadata.creationTime. In the beta version, to get the last signed in time, you would just write userMetadata.lastSignedInAt, but now, you can write userRecord.metadata.lastSignedInTime. So we see that instead of using the event.data, now we can simply use the userRecord parameter.

Summary

On this module, which is the last one for this course, we talked about some of the major differences and how we can upgrade from beta version to version 1.0. We started by talking about the background non-HTTP functions where we learned that the background functions now don’t have only one parameter, but two. Then we talked about the initialization syntax and how we don’t need the functions.config anymore when initializing the Firebase admin. Then next, we talked about the SDK changes by trigger type, so we talked about the Realtime Database, the Cloud Firestore, authentication, and storage.