Firebase Cloud Functions: Introduction and Project Setup

If your Flutter app needs a backend, Firebase offers many useful services that let you ship faster.

And by adding Cloud Functions to the mix, you can run custom backend code without having to worry about managing and scaling your own servers.

This tutorial will give you a broad overview about Cloud Functions for Firebase and guide you through all the required installation steps.

What are Cloud Functions?

Cloud Functions are a way to write your own serverless, event-driven backend.

Serverless means that you can use them to deploy your backend code without having to provision any servers.

Cloud Functions automatically scale based on the load, and they have strong security built-in. As a result, they offer a great development experience because you can focus on what matters: writing your backend code.

So how do we run Cloud Functions?

Triggers

Cloud Functions run in response to events inside Google Cloud services, including any Firebase products that you may be using.

In other words:

Cloud Functions are triggered in response to events.

Cloud Functions for Firebase: Triggers
Cloud Functions for Firebase: Triggers

There are many triggers that you can use, such as:

  • Writes to Cloud Firestore
  • Uploads to Cloud Storage
  • New accounts in Firebase Authentication
  • Analytics conversion events
  • Crashlytics events
  • Incoming HTTPS requests

If you want, you can even run Cloud Functions periodically on a schedule.

When you use Cloud Functions, your code runs on Google servers, keeping your application logic centralized and safe. So Cloud Functions are a good place to store and run any code that should not live on the client.

Examples

Here are a few examples of things that you can do with Cloud Functions:

  • Authentication trigger to send a welcome email when a new user signs in.
  • Receive an email or a Slack notification when a new issue is discovered in Crashlytics.
  • Generate a thumbnail when a user uploads an image to Firebase Storage.
  • Moderate or remove any offensive words that are entered by a user inside your app.
  • Send a FCM notification to users in your app (useful for chat applications).
  • Index your Firestore DB and implement full-text search by tapping into external services like Algolia.

This sounds good. But before you can write your own Cloud Functions, you need to learn about Node.js.

Node.js

Node.js is a runtime that allows you to write JavaScript code that runs on the server.

It was introduced in 2009 and has become very popular, allowing web developers to write full-stack applications using a single language: JavaScript.

Since Cloud Functions run on the Node.js runtime, you need to write Cloud Functions in JavaScript (or a language that can be compiled to JavaScript).

And if you are writing Cloud Functions for Firebase, then the only languages that are officially supported are JavaScript, TypeScript, and Python (as of May 2023).

Note: Node.js is hugely popular and many companies use it to write backend apps in JavaScript (or TypeScript). You can use it to build your own REST APIs using Express.js, and it also supports GraphQL and databases such as MongoDB. To learn more, watch: Node.js Tutorial for Beginners: Learn Node in 1 Hour

But let's stay on track and focus on Cloud Functions. 👇

Firebase Cloud Functions: Setup Guide

First of all, we'll install all the required tools. Then, we'll deploy our first Cloud Function.

1. Install node

You can follow the instructions on this page to download and install the recommended Node.js version on your platform.

Your node installation will also include the Node Package Manager (npm). Think of npm as the Javascript equivalent of pub for Dart packages.

You can run node -v and npm -v to check which versions are installed.

If you need multiple versions of Node on your system, consider using Node Version Manager.

2. Install the Firebase CLI

Firebase CLI is a command line tool that you can use to manage your Firebase projects.

You can install it globally on your system by running:

npm install -g firebase-tools

3. Initialize a new Firebase project

Next, you're ready to create a new Firebase project.

In the Firebase console, add a new project and give it a name (e.g. hello-world).

You'll be asked if you want to enable Google Analytics. You can skip that and create the project.

In this tutorial, we will focus on Cloud Functions only. If you want to use Firebase in your Flutter app, you need to do some additional configuration. The documentation includes guides for Apple platforms, Android and Web.

Back on the terminal, create a new folder and move to it:

mkdir hello-world cd hello-world

At this stage, you can use the terminal to complete the remaining steps. But if you prefer to use VSCode, just run code . to open a VSCode window on the current folder. Then you can use the integrated terminal to complete the setup.

Next, let's login with Firebase and confirm at the command prompt:

> firebase login Allow Firebase to collect CLI usage and error reporting information? (Y/n)

This takes us to a browser window where we can sign in with your Google Account, and authorize Firebase CLI to access it.

Once logged in, we can get back to VS code and initialize a new Firebase project:

firebase init

This will show an interactive prompt where we can select the Firebase features we want to enable:

######## #### ######## ######## ######## ### ###### ######## ## ## ## ## ## ## ## ## ## ## ## ###### ## ######## ###### ######## ######### ###### ###### ## ## ## ## ## ## ## ## ## ## ## ## #### ## ## ######## ######## ## ## ###### ######## You're about to initialize a Firebase project in this directory: /Users/andrea/work/codewithandrea/github/firebase-scratch/hello-world ? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. (Press <space> to select, <a> to toggle all, <i> to invert selectio n) ❯◯ Database: Deploy Firebase Realtime Database Rules Firestore: Deploy rules and create indexes for Firestore Functions: Configure and deploy Cloud Functions Hosting: Configure and deploy Firebase Hosting sites Storage: Deploy Cloud Storage security rules Emulators: Set up local emulators for Firebase features

For this example, we'll select Functions only.

Next, this prompt shows:

=== Project Setup First, let's associate this project directory with a Firebase project. You can create multiple project aliases by running firebase use --add, but for now we'll just set up a default project. ? Please select an option: (Use arrow keys) Use an existing project Create a new project Add Firebase to an existing Google Cloud Platform project Don't set up a default project

We can choose "Use an existing project" and select the project we created earlier in the Firebase console.

Next, let's choose which language to use:

=== Functions Setup A functions directory will be created in your project with a Node.js package pre-configured. Functions can be deployed with firebase deploy. ? What language would you like to use to write Cloud Functions? (Use arrow keys) JavaScript TypeScript

I recommend using TypeScript. Next:

Do you want to use ESLint to catch probable bugs and enforce style? (Y/n)

In general, it's recommended to add linting to your project. Though the default settings for ESLint are quite strict and you may struggle with them if you're not very experienced with TypeScript. Feel free to disable this for this tutorial.

A few files will be created:

Wrote functions/package.json Wrote functions/tslint.json Wrote functions/tsconfig.json Wrote functions/src/index.ts Wrote functions/.gitignore

Next, we're asked to install dependencies:

? Do you want to install dependencies with npm now? (Y/n)

Let's select "Y" to install dependencies. This will take a few seconds and after that our project is ready!

Project overview

We now have some new files in the project:

functions/ node_modules/ src/ index.ts .gitignore package-lock.json package.json tsconfig.json tslint.json .firebaserc .gitignore firebase.json

The generated package.json file looks like this:

{ "name": "functions", "scripts": { "build": "tsc", "serve": "npm run build && firebase emulators:start --only functions", "shell": "npm run build && firebase functions:shell", "start": "npm run shell", "deploy": "firebase deploy --only functions", "logs": "firebase functions:log" }, "engines": { "node": "14" }, "main": "lib/index.js", "dependencies": { "firebase-admin": "^9.8.0", "firebase-functions": "^3.14.1" }, "devDependencies": { "typescript": "^3.8.0", "firebase-functions-test": "^0.2.0" }, "private": true }

Note that the dependencies section includes the firebase-admin and firebase-functions packages that were installed by npm earlier on.

If we want to add any more packages, we can add run npm install <package-name>, which in turn will:

  • Include the new packages as dependencies inside package.json
  • Install them (along with their dependencies) inside the node_modules folder.

node_modules contains a lot of stuff. Since npm manages it for you, this folder is added to .gitignore by default.

Hello World

Our project is now ready and we can start writing our first Cloud Function.

The entry point for the project is defined in functions/src/index.ts. By default it looks like this:

import * as functions from 'firebase-functions'; // // Start writing Firebase Functions // // https://firebase.google.com/docs/functions/typescript // // export const helloWorld = functions.https.onRequest((request, response) => { // response.send("Hello from Firebase!"); // });

You can uncomment the lines above to enable the helloWorld Cloud Function.

export const helloWorld = functions.https.onRequest((request, response) => { response.send("Hello from Firebase!"); });

This is a simple http function that we can use to respond to a web request. All we do here is to use the response argument to send a string as a response back to the client.

Deploying our first Cloud Function

Now that we have a Cloud Function, let's deploy it!

From the terminal, we can type:

cd functions firebase deploy

As part of this, a few steps take place:

  • The TypeScript linter runs and checks our code (if we enabled it earlier on).
  • Our cloud function is compiled to JavaScript so that it can run on the Node.js runtime.
  • Finally, it is deployed to a server on the Google Cloud Platform.

Once this process is complete, the function URL is printed on the console:

=== Deploying to 'hello-world-58ab7'... i deploying functions Running command: npm --prefix "$RESOURCE_DIR" run build > functions@ build /Users/andrea/work/codewithandrea/github/firebase-scratch/hello-world/functions > tsc functions: Finished running predeploy script. i functions: ensuring necessary APIs are enabled... functions: all necessary APIs are enabled i functions: preparing functions directory for uploading... i functions: packaged functions (34.87 KB) for uploading functions: functions folder uploaded successfully i functions: creating Node.js 8 function helloWorld(us-central1)... functions[helloWorld(us-central1)]: Successful create operation. Function URL (helloWorld): https://us-central1-hello-world-58ab7.cloudfunctions.net/helloWorld Deploy complete! Project Console: https://console.firebase.google.com/project/hello-world-58ab7/overview

If we open the output URL in the browser, we can see the "Hello from Firebase!" response on screen.

Congratulations! You have deployed your first Cloud Function! 🚀

Conclusion

Cloud Functions are a broad topic and there is much more to learn.

Luckily, the Firebase team has already published a very good video series on Cloud Functions:

This covers many useful concepts such as:

  • Promises, async, await in TypeScript
  • Error handling
  • Cloud Function triggers

Once you're familiar with the basics, check out the Functions Samples Library from the Firebase team:

All the source code for this project is written in JavaScript. But it's a great resource if you want to learn about many use cases for Cloud Functions.

And if you're up for a challenge, you can try converting some of the samples to TypeScript.

Additional Resources

The official Cloud Functions for Firebase documentation contains everything you need to get started.

In particular, I found these resources useful:

New Flutter & Firebase Course

If you want to ship your Flutter apps faster, Firebase is a great choice. And in this new course, I cover all the most important features, including Firebase Auth, Cloud Firestore, Firebase Storage, Cloud Functions, and Firebase Extensions. 👇

Want More?

Invest in yourself with my high-quality Flutter courses.

Flutter In Production

Flutter In Production

Learn about flavors, environments, error monitoring, analytics, release management, CI/CD, and finally ship your Flutter apps to the stores. 🚀

Flutter Foundations Course

Flutter Foundations Course

Learn about State Management, App Architecture, Navigation, Testing, and much more by building a Flutter eCommerce app on iOS, Android, and web.

The Complete Dart Developer Guide

The Complete Dart Developer Guide

Learn Dart Programming in depth. Includes: basic to advanced topics, exercises, and projects. Last updated to Dart 2.15.

Flutter Animations Masterclass

Flutter Animations Masterclass

Master Flutter animations and build a completely custom habit tracking application.