Get started: write, test, and deploy your first functions (1st gen)

To get started with Cloud Functions , try working through this tutorial, which starts with the required setup tasks and works through creating, testing, and deploying two related functions:

  • An "add message" function that exposes a URL that accepts a text value and writes it to Cloud Firestore .
  • A "make uppercase" function that triggers on a Cloud Firestore write and transforms the text to uppercase.

We've chosen Cloud Firestore and HTTP-triggered JavaScript functions for this sample in part because these background triggers can be thoroughly tested through the Firebase Local Emulator Suite . This toolset also supports Realtime Database , PubSub, Auth, and HTTP callable triggers. Other types of background triggers such as Remote Config , TestLab, and Analytics triggers can all be tested interactively using toolsets not described in this page.

The following sections of this tutorial detail the steps required to build, test, and deploy the sample. If you'd rather just run the code and inspect it, jump to Review complete sample code .

Create a Firebase Project

New to Firebase or Cloud

Follow these steps if you're new to Firebase or Google Cloud .You can also follow these steps if you want to create a wholly new Firebase project (and its underlying Google Cloud project).

  1. Sign into the Firebase console .
  2. Click the button to create a new Firebase project.
  3. In the text field, enter a project name .

    If you're part of a Google Cloud org, you can optionally select which folder you create your project in.

  4. If prompted, review and accept the Firebase terms , then click Continue .
  5. (Optional) Enable AI assistance in the Firebase console (called "Gemini in Firebase"), which can help you get started and streamline your development process.
  6. (Optional) Set up Google Analytics for your project, which enables an optimal experience using these Firebase products: Firebase A/B Testing , Cloud Messaging , Crashlytics , In-App Messaging , and Remote Config (including Personalization ).

    Either select an existing Google Analytics account or create a new account. If you create a new account, select your Analytics reporting location , then accept the data sharing settings and Google Analytics terms for your project.

  7. Click Create project .

Firebase creates your project, provisions some initial resources, and enables important APIs. When the process completes, you'll be taken to the overview page for your Firebase project in the Firebase console.

Existing Cloud project

Follow these steps if you want to start using Firebase with an existing Google Cloud project. Learn more about "adding Firebase" to an existing Google Cloud project .

  1. Sign into the Firebase console with the account that gives you access to the existing Google Cloud project.
  2. Click the button to create a new Firebase project.
  3. At the bottom of the page, click Add Firebase to Google Cloud project .
  4. In the text field, start entering the project name of the existing project, and then select the project from the displayed list.
  5. Click Open project .
  6. If prompted, review and accept the Firebase terms , then click Continue .
  7. (Optional) Enable AI assistance in the Firebase console (called "Gemini in Firebase"), which can help you get started and streamline your development process.
  8. (Optional) Set up Google Analytics for your project, which enables an optimal experience using these Firebase products: Firebase A/B Testing , Cloud Messaging , Crashlytics , In-App Messaging , and Remote Config (including Personalization ).

    Either select an existing Google Analytics account or create a new account. If you create a new account, select your Analytics reporting location , then accept the data sharing settings and Google Analytics terms for your project.

  9. Click Add Firebase .

Firebase adds Firebase to your existing project . When the process completes, you'll be taken to the overview page for your Firebase project in the Firebase console.

Set up Node.js and the Firebase CLI

You'll need a Node.js environment to write functions, and you'll need the Firebase CLI to deploy functions to the Cloud Functions runtime. For installing Node.js and npm , Node Version Manager is recommended.

Once you have Node.js and npm installed, install the Firebase CLI via your preferred method. To install the CLI via npm, use:

  npm 
  
 install 
  
 - 
 g 
  
 firebase 
 - 
 tools 
 

This installs the globally available firebase command. If the command fails, you may need to change npm permissions . To update to the latest version of firebase-tools , rerun the same command.

Initialize your project

When you initialize Firebase SDK for Cloud Functions , you create an empty project containing dependencies and some minimal sample code, and you choose either TypeScript or JavaScript for composing functions. For the purposes of this tutorial, you'll also need to initialize Cloud Firestore .

To initialize your project:

  1. Run firebase login to log in via the browser and authenticate the Firebase CLI.

  2. Go to your Firebase project directory.

  3. Run firebase init firestore . For this tutorial, you can accept the default values when prompted for Firestore rules and index files. If you haven't used Cloud Firestore in this project yet, you'll also need to select a starting mode and location for Firestore as described in Get started with Cloud Firestore .

  4. Run firebase init functions . The CLI prompts you to choose an existing codebase or initialize and name a new one. When you're just getting started, a single codebase in the default location is adequate; later, as your implementation expands, you might want to organize functions in codebases .

  5. The CLI gives you the following options for language support:

    For this tutorial, select JavaScript.

  6. The CLI gives you an option to install dependencies with npm. It is safe to decline if you want to manage dependencies in another way, though if you do decline you'll need to run npm install before emulating or deploying your functions.

After these commands complete successfully, your project structure looks like this:

  myproject 
+- . firebaserc 
 # Hidden file that helps you quickly switch between 
| # projects with `firebase use` 
|
 +- firebase 
. json 
 # Describes properties for your project 
|
 +- functions 
/ # Directory containing all your functions code 
|
      +- . eslintrc 
. json 
 # Optional file containing rules for JavaScript linting. 
|
      +- package 
. json 
 # npm package file describing your Cloud Functions 
code 
|
      +- index 
. js 
 # main source file for your Cloud Functions 
code 
|
      +- node_modules 
/ # directory where your dependencies (declared in 
 # package.json) are installed 
 

The package.json file created during initialization contains an important key: "engines": {"node": "16"} . This specifies your Node.js version for writing and deploying functions. You can select other supported versions .

Import the required modules and initialize an app

After you have completed the setup tasks, you can open the source directory and start adding code as described in the following sections. For this sample, your project must import the Cloud Functions and Admin SDK modules using Node require statements. Add lines like the following to your index.js file:

 // 
  
 The 
  
 Cloud 
  
 Functions 
  
 for 
  
 Firebase 
  
 SDK 
  
 to 
  
 create 
  
 Cloud 
  
 Functions 
  
 and 
  
 set 
  
 up 
  
 triggers 
 . 
 const 
  
 functions 
  
 = 
  
 require 
 ( 
 'firebase-functions/v1' 
 ); 
 // 
  
 The 
  
 Firebase 
  
 Admin 
  
 SDK 
  
 to 
  
 access 
  
 Firestore 
 . 
 const 
  
 admin 
  
 = 
  
 require 
 ( 
 "firebase-admin" 
 ); 
 admin 
 . 
 initializeApp 
 (); 
  

These lines load the firebase-functions and firebase-admin modules, and initialize an admin app instance from which Cloud Firestore changes can be made. Wherever Admin SDK support is available, as it is for FCM , Authentication , and Firebase Realtime Database , it provides a powerful way to integrate Firebase using Cloud Functions .

The Firebase CLI automatically installs the Firebase and Firebase SDK for Cloud Functions Node modules when you initialize your project. To add 3rd party libraries to your project, you can modify package.json and run npm install . For more information, see Handle Dependencies .

Add the addMessage() function

For the addMessage() function, add these lines to index.js :

 // 
  
 Take 
  
 the 
  
 text 
  
 parameter 
  
 passed 
  
 to 
  
 this 
  
 HTTP 
  
 endpoint 
  
 and 
  
 insert 
  
 it 
  
 into 
 // 
  
 Firestore 
  
 under 
  
 the 
  
 path 
  
 / 
 messages 
 / 
 : 
 documentId 
 / 
 original 
 exports 
 . 
 addMessage 
  
 = 
  
 functions 
 . 
 https 
 . 
 onRequest 
 ( 
 async 
  
 ( 
 req 
 , 
  
 res 
 ) 
  
 = 
>  
 { 
  
 // 
  
 Grab 
  
 the 
  
 text 
  
 parameter 
 . 
  
 const 
  
 original 
  
 = 
  
 req 
 . 
 query 
 . 
 text 
 ; 
  
 // 
  
 Push 
  
 the 
  
 new 
  
 message 
  
 into 
  
 Firestore 
  
 using 
  
 the 
  
 Firebase 
  
 Admin 
  
 SDK 
 . 
  
 const 
  
 writeResult 
  
 = 
  
 await 
  
 admin 
  
 . 
 firestore 
 () 
  
 . 
 collection 
 ( 
 "messages" 
 ) 
  
 . 
 add 
 ({ 
  
 original 
 : 
  
 original 
  
 }); 
  
 // 
  
 Send 
  
 back 
  
 a 
  
 message 
  
 that 
  
 we 
 've successfully written the message 
  
 res 
 . 
 json 
 ({ 
  
 result 
 : 
  
 ` 
 Message 
  
 with 
  
 ID 
 : 
  
 $ 
 { 
 writeResult 
 . 
 id 
 } 
  
 added 
 . 
 ` 
  
 }); 
 }); 
  

The addMessage() function is an HTTP endpoint. Any request to the endpoint results in ExpressJS-style Request and Response objects passed to the onRequest() callback.

HTTP functions are synchronous (similar to callable functions ), so you should send a response as quickly as possible and defer work using Cloud Firestore . The addMessage() HTTP function passes a text value to the HTTP endpoint and inserts it into the database under the path /messages/:documentId/original .

Add the makeUppercase() function

For the makeUppercase() function, add these lines to index.js :

 // 
  
 Listens 
  
 for 
  
 new 
  
 messages 
  
 added 
  
 to 
  
 / 
 messages 
 / 
 : 
 documentId 
 / 
 original 
  
 and 
  
 creates 
  
 an 
 // 
  
 uppercase 
  
 version 
  
 of 
  
 the 
  
 message 
  
 to 
  
 / 
 messages 
 / 
 : 
 documentId 
 / 
 uppercase 
 exports 
 . 
 makeUppercase 
  
 = 
  
 functions 
 . 
 firestore 
  
 . 
 document 
 ( 
 "/messages/{documentId}" 
 ) 
  
 . 
 onCreate 
 (( 
 snap 
 , 
  
 context 
 ) 
  
 = 
>  
 { 
  
 // 
  
 Grab 
  
 the 
  
 current 
  
 value 
  
 of 
  
 what 
  
 was 
  
 written 
  
 to 
  
 Firestore 
 . 
  
 const 
  
 original 
  
 = 
  
 snap 
 . 
 data 
 () 
 . 
 original 
 ; 
  
 // 
  
 Access 
  
 the 
  
 parameter 
  
 ` 
 { 
 documentId 
 } 
 ` 
  
 with 
  
 ` 
 context 
 . 
 params 
 ` 
  
 functions 
 . 
 logger 
 . 
 log 
 ( 
 "Uppercasing" 
 , 
  
 context 
 . 
 params 
 . 
 documentId 
 , 
  
 original 
 ); 
  
 const 
  
 uppercase 
  
 = 
  
 original 
 . 
 toUpperCase 
 (); 
  
 // 
  
 You 
  
 must 
  
 return 
  
 a 
  
 Promise 
  
 when 
  
 performing 
  
 asynchronous 
  
 tasks 
  
 inside 
  
 a 
  
 Functions 
  
 such 
  
 as 
  
 // 
  
 writing 
  
 to 
  
 Firestore 
 . 
  
 // 
  
 Setting 
  
 an 
  
 'uppercase' 
  
 field 
  
 in 
  
 Firestore 
  
 document 
  
 returns 
  
 a 
  
 Promise 
 . 
  
 return 
  
 snap 
 . 
 ref 
 . 
 set 
 ({ 
  
 uppercase 
  
 }, 
  
 { 
  
 merge 
 : 
  
 true 
  
 }); 
  
 }); 
  

The makeUppercase() function executes when Cloud Firestore is written to. The ref.set function defines the document to listen on. For performance reasons, you should be as specific as possible.

Braces—for example, {documentId} —surround "parameters," wildcards that expose their matched data in the callback.

Cloud Firestore triggers the onCreate() callback whenever new messages are added.

Event-driven functions such as Cloud Firestore events are asynchronous. The callback function should return either a null , an Object, or a Promise . If you do not return anything, the function times out, signaling an error, and is retried. See Sync, Async, and Promises .

Emulate execution of your functions

The Firebase Local Emulator Suite allows you to build and test apps on your local machine instead of deploying to a Firebase project. Local testing during development is strongly recommended, in part because it lowers the risk from coding errors that could potentially incur cost in a production environment (for example, an infinite loop).

To emulate your functions:

  1. Run firebase emulators:start and check the output for the URL of the Emulator Suite UI . It defaults to localhost:4000 , but may be hosted on a different port on your machine. Enter that URL in your browser to open the Emulator Suite UI .

  2. Check the output of the firebase emulators:start command for the URL of the HTTP function addMessage() . It will look similar to http://localhost:5001/MY_PROJECT/us-central1/addMessage , except that:

    1. MY_PROJECT will be replaced with your project ID.
    2. The port may be different on your local machine.
  3. Add the query string ?text=uppercaseme to the end of the function's URL. This should look something like: http://localhost:5001/MY_PROJECT/us-central1/addMessage?text=uppercaseme . Optionally, you can change the message "uppercaseme" to a custom message.

  4. Create a new message by opening the URL in a new tab in your browser.

  5. View the effects of the functions in the Emulator Suite UI :

    1. In the Logstab, you should see new logs indicating that the functions addMessage() and makeUppercase() ran:

      i functions: Beginning execution of "addMessage"

      i functions: Beginning execution of "makeUppercase"

    2. In the Firestoretab, you should see a document containing your original message as well as the uppercased version of your message (if it was originally "uppercaseme", you'll see "UPPERCASEME").

Deploy functions to a production environment

Once your functions are working as desired in the emulator, you can proceed to deploying, testing, and running them in the production environment. Keep in mind that to deploy to the Node.js 14 runtime environment, your project must be on the Blaze pricing plan . See Cloud Functions pricing .

To complete the tutorial, deploy your functions and then execute addMessage() to trigger makeUppercase() .

  1. Run this command to deploy your functions:

    firebase deploy --only functions

    After you run this command, the Firebase CLI outputs the URL for any HTTP function endpoints. In your terminal, you should see a line like the following:

     Function URL (addMessage): https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage 
    

    The URL contains your project ID as well as a region for the HTTP function. Though you don't need to worry about it now, some production HTTP functions should specify a location to minimize network latency.

    If you encounter access errors such as "Unable to authorize access to project," try checking your project aliasing .

  2. Using the addMessage() URL output by the CLI, add a text query parameter, and open it in a browser:

     https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage?text=uppercasemetoo 
    

    The function executes and redirects the browser to the Firebase console at the database location where the text string is stored. This write event triggers makeUppercase() , which writes an uppercase version of the string.

After deploying and executing functions, you can view logs in the Google Cloud console . If you need to delete functions in development or production, use the Firebase CLI.

In production, you may want to optimize function performance and control costs by setting minimum and maximum numbers of instances to run. See Control scaling behavior for more information on these runtime options.

Review complete sample code

Here's the completed functions/index.js containing the functions addMessage() and makeUppercase() . These functions allow you to pass a parameter to an HTTP endpoint that writes a value to Cloud Firestore , and then transforms it by uppercasing all characters in the string.

 // 
  
 The 
  
 Cloud 
  
 Functions 
  
 for 
  
 Firebase 
  
 SDK 
  
 to 
  
 create 
  
 Cloud 
  
 Functions 
  
 and 
  
 set 
  
 up 
  
 triggers 
 . 
 const 
  
 functions 
  
 = 
  
 require 
 ( 
 'firebase-functions/v1' 
 ); 
 // 
  
 The 
  
 Firebase 
  
 Admin 
  
 SDK 
  
 to 
  
 access 
  
 Firestore 
 . 
 const 
  
 admin 
  
 = 
  
 require 
 ( 
 "firebase-admin" 
 ); 
 admin 
 . 
 initializeApp 
 (); 
 // 
  
 Take 
  
 the 
  
 text 
  
 parameter 
  
 passed 
  
 to 
  
 this 
  
 HTTP 
  
 endpoint 
  
 and 
  
 insert 
  
 it 
  
 into 
 // 
  
 Firestore 
  
 under 
  
 the 
  
 path 
  
 / 
 messages 
 / 
 : 
 documentId 
 / 
 original 
 exports 
 . 
 addMessage 
  
 = 
  
 functions 
 . 
 https 
 . 
 onRequest 
 ( 
 async 
  
 ( 
 req 
 , 
  
 res 
 ) 
  
 = 
>  
 { 
  
 // 
  
 Grab 
  
 the 
  
 text 
  
 parameter 
 . 
  
 const 
  
 original 
  
 = 
  
 req 
 . 
 query 
 . 
 text 
 ; 
  
 // 
  
 Push 
  
 the 
  
 new 
  
 message 
  
 into 
  
 Firestore 
  
 using 
  
 the 
  
 Firebase 
  
 Admin 
  
 SDK 
 . 
  
 const 
  
 writeResult 
  
 = 
  
 await 
  
 admin 
  
 . 
 firestore 
 () 
  
 . 
 collection 
 ( 
 "messages" 
 ) 
  
 . 
 add 
 ({ 
  
 original 
 : 
  
 original 
  
 }); 
  
 // 
  
 Send 
  
 back 
  
 a 
  
 message 
  
 that 
  
 we 
 've successfully written the message 
  
 res 
 . 
 json 
 ({ 
  
 result 
 : 
  
 ` 
 Message 
  
 with 
  
 ID 
 : 
  
 $ 
 { 
 writeResult 
 . 
 id 
 } 
  
 added 
 . 
 ` 
  
 }); 
 }); 
 // 
  
 Listens 
  
 for 
  
 new 
  
 messages 
  
 added 
  
 to 
  
 / 
 messages 
 / 
 : 
 documentId 
 / 
 original 
  
 and 
  
 creates 
  
 an 
 // 
  
 uppercase 
  
 version 
  
 of 
  
 the 
  
 message 
  
 to 
  
 / 
 messages 
 / 
 : 
 documentId 
 / 
 uppercase 
 exports 
 . 
 makeUppercase 
  
 = 
  
 functions 
 . 
 firestore 
  
 . 
 document 
 ( 
 "/messages/{documentId}" 
 ) 
  
 . 
 onCreate 
 (( 
 snap 
 , 
  
 context 
 ) 
  
 = 
>  
 { 
  
 // 
  
 Grab 
  
 the 
  
 current 
  
 value 
  
 of 
  
 what 
  
 was 
  
 written 
  
 to 
  
 Firestore 
 . 
  
 const 
  
 original 
  
 = 
  
 snap 
 . 
 data 
 () 
 . 
 original 
 ; 
  
 // 
  
 Access 
  
 the 
  
 parameter 
  
 ` 
 { 
 documentId 
 } 
 ` 
  
 with 
  
 ` 
 context 
 . 
 params 
 ` 
  
 functions 
 . 
 logger 
 . 
 log 
 ( 
 "Uppercasing" 
 , 
  
 context 
 . 
 params 
 . 
 documentId 
 , 
  
 original 
 ); 
  
 const 
  
 uppercase 
  
 = 
  
 original 
 . 
 toUpperCase 
 (); 
  
 // 
  
 You 
  
 must 
  
 return 
  
 a 
  
 Promise 
  
 when 
  
 performing 
  
 asynchronous 
  
 tasks 
  
 inside 
  
 a 
  
 Functions 
  
 such 
  
 as 
  
 // 
  
 writing 
  
 to 
  
 Firestore 
 . 
  
 // 
  
 Setting 
  
 an 
  
 'uppercase' 
  
 field 
  
 in 
  
 Firestore 
  
 document 
  
 returns 
  
 a 
  
 Promise 
 . 
  
 return 
  
 snap 
 . 
 ref 
 . 
 set 
 ({ 
  
 uppercase 
  
 }, 
  
 { 
  
 merge 
 : 
  
 true 
  
 }); 
  
 }); 
  

Next steps

In this documentation, you can learn more about how to manage functions for Cloud Functions as well as how to to handle all event types supported by Cloud Functions .

To learn more about Cloud Functions , you could also do the following:

Design a Mobile Site
View Site in Mobile | Classic
Share by: