How to Send Emails from Contact Form Using Firebase Functions

This post comes as the cherry on top of the firepage post series.

Here I’m going to show you how to send emails to your email address from a contact form and use Firebase Functions to stay notified about new leads.

firebase functions send emails

There are a bunch of guides on the web explaining how to host on firebase or make your contact form work and store leads into the database.


All of that is a waste of time if you can’t forward your leads from a website to your email, and get NOTIFIED about it. Before the article you’re reading now, there were ZERO guides explaining how to do so.

Obviously, you don’t want to log into your real-time database every day and check it manually, even if some services still make you do that. (Come on Facebook Lead Forms, it’s 2019 already!)

First let’s set everything up.

Learn What You Need to Know Before We Begin

The whole method takes 10-20 minutes, and it requires basic knowledge of JavaScript and copy skills. When you’re done, you’ll get leads forwarded to your email from Firebase. I highly doubt that there is a simpler way.

This article is a continuation of a series of posts where we’re creating a landing page from scratch using Google Firebase – The Firepage Landing. Let’s quickly recap what we did before starting with your lead forwarding:

  • We picked a free/paid ready-made HTML5 template
  • Hosted it on Firebase Hosting
  • Bought and attached a domain to it
  • Created a real-time database
  • Made a working contact form and started storing leads in the database

Now every time a user enters an email into the email box on a website and hits the submit button, his email is getting stored in the Firebase Real-time Database. Let’s forward that data to your email.

3 Steps to Send Emails from the Contact Form on Firebase

The strategy here’s very simple. Every time your Real-time Database gets modified, you want to grab those changes and send them over to your email.

So we define 3 steps here:

  1. Initialize Firebase functions
  2. Install a mail forwarding application
  3. Configure firebase functions

Every time you get a lead, that lead gets forwarded to your email.

Luckily for us, all events are already a part of Firebase functions. For sending emails, we’re going to install an external Node.JS application.

But don’t run away, this is MUCH simpler than it sounds.

Step #1: Initialize Firebase Functions

Go to console/terminal, move to your project folder and type “firebase init”.

deploy firebase functions

Then do everything it tells you to. There is no wrong answer and Google gives you clear instructions.

Once you get it done, the function folder is going to appear in a project folder.

Step #2: Installing the Nodemailer Application for Sending Emails

As you see, there are 2 files: package.json and index.js

Package.json is responsible for applications running on your firebase functions server. We just need to add 3 lines of code to install the mail forwarding app – Nodemailer.

firebase functions start screen

Go to your console, move to /your-project/function and install the new Nodemailer app.

Return back to your project folder. Not that hard, huh?  Now our Firepage can send Emails!

Step #3: Learn How to Configure Firebase Functions

Here I have prepared a good chunk of code with an explanation of how it works. This is also available on Codepen

firebase functions Nodemailer configs

Just copy paste that from the Codepen.

You may notice that I use “functions.config().gmail.login” to get the login and password: you can use just a plain text instead.

const gmailEmail = “” - this is going to work as well.

However, it’s not secure if you ever plan to share your code on Github, for example.

I recommend that you use the Firebase functions environment object to store your secure information, such as passwords, logins, emails, etc. Here is how to access it:

firebase functions:config:set gmail.pass=yourpass

functions.config() to access that object*.

*Firebase functions:config:getto see any data you stored
**Firebase functions:config:unset gmailto deletefirebase functions privacy config

Go ahead and try it, copy and paste that code and change the example data to yours.

Tip: There are ways to use not only Gmail but you would have to more deeply configure your transporter functions.

Once everything is configured and the recipient email is correct, deploy your project.

Step #4: Test Your Contact Form to Make Sure Everything Works Correctly

Go to your webpage and enter some data into your fields. Click the submit button. 😉

testing firebase function emails

If you did everything correctly and in the right order, you should get an email notification.

nodemailer notification

You’re probably also going to want to make sure everything works as expected. Check out the project logs in your Firebase console. Besides, this is also the simplest way to debug your contact form using Firebase Functions.

Firebase and Node mailer debug

Firepage Landing Post Series

Congratulations! You have successfully created your first Firepage Landing.

Now you can install Google analytics and search the console, assign custom conversion, create nice looking popups, and much more. In less than 3 hours you made it from zero to hero and created a fully working landing page.

Now leave a comment below and tell me more about your journey!

The Firepage Landing:
Part #1: Pick a Landing Page Template and Host It on Firebase (Firebase Hosting)
Part #2: Set up a Database to Store your Leads (Real-Time Database)

Want more content like this? Sign up for my newsletter – it’s free!


I have a degree in marketing communication and work as a marketer in a software development company. Usually, I watch a marketing course or webinar a day, but sometimes I shift to programming, finances or lifestyle books.


    • Alex Reply

      Hi, Michael! That means that you probably have not installed nodeJS or some packages. Hit me up on Twitter with a screenshot and I’ll help you fix it.

  1. I figured it out, I was writing the function script to the wrong index,js file. If I recall it had been a long day 🙁

    Now, however, I’m having trouble getting any error/success message returned from sendMail. How do I send a message from the functions script back to my web page?

    • Alex Reply

      Are you looking for Success/Error Message in Firebase Console?
      The first thing you should look for: Is data successfully storing in your real-time database? If it is, look for a database trigger: “exports.onDataAdded”. Make sure it’s firing correctly by adding a console.log… and check status in function logs. If it’s not firing, probably you have to change a path or smth …

      You don’t really need to send messages from functions to your webpage. I prefer to count successful push to the real-time database as a success. BUT if you really want to send messages from functions to your frontend you probably need to store it in the database first and then request it using JS on the frontend. Although, I’m not a Node.js expert just yet. 😉

  2. Getting an error when trying to deploy. Says it can’t find nodemailer, even though I have it installed in the /functions/node_modules folder. It’s also listed in the functions/package.json under devDependencies like you have in the post.

    The full error is here:

    • Alex Reply

      Hi, Ethan! Is it listed under regular dependencies? Here is my package.json from firebase functions folder Nodemailer should be listed just under ‘regular dependencies’ in order to work. Dev dependencies are not necessary. If you still have a problem, hit me up via twitter @tech_trench. I’ll help you in real time!

      • I feel dumb, it wasn’t. Deployed successfully. Thanks for the quick reply.

        Now I’m getting an error in the firebase functions logs, it says Error: Invalid login: Application-specific password required. Learn more at

        From what I read it is because I have a 2-step authentication enabled on my google account. How can I make this work with this website?

        • Alex Reply

          For my latest project, I just created a new Gmail account. Don’t forget to enable Less Secure Apps that might be a thing too, and check your email box as well. Sometimes Google sends you an email like “An external app is trying to use your account … Approve or Decline”.

          • Set up a new email and got it working! Thank’s for all your help Alex.

    • Alex Reply

      Sure thing Ram, send me a dm via twitter @tech_trench and I’ll send you the link.

      • Dear sir, I had messaged you many times please respond to me.

  3. Hi Alex,

    I’m reaching out to you regarding your tutorial How to Send Emails from Contact Form Using Firebase Functions. I was also writing a comment with my question, but can’t find it anymore?!

    Anyway, I have a problem with making Contact form working correctly. I followed your guide, and everything seems to work fine except the most important thing. The emails that come from Firebase function have the “!undefined” in the subject line. No data is inside the emails. May you please help me to find out what is getting wrong here? And here is the log from Functions in Firebase.

    10:27:51.649 AM
    Function execution started

    10:27:51.908 AM
    Function returned undefined, expected Promise or value.

    10:27:51.914 AM
    Function execution took 266 ms, finished with status: ‘ok.’

    10:28:01.007 AM
    Message sent:

    Otherwise great tutorials! Thank you.


    • Alex Reply

      Sure thing, Henrick. Thank you for reaching out. If you are getting undefined, that happens from one of the two reasons:

      a) There is a disconnect between variables you stored and you are trying to pull. For example – here we are trying to pull “mail” variable from the record we just created. (blue) And here we are storing that information. – (prev article explains). So if you stored for example “email” and you are trying to pull “mail” you are gonna get undefined.

      b) You have not stored data at all, maybe there is a mistake at previous steps and you are not creating records in the database. In that case, you have to make sure you do.

  4. Weiting Xu Reply

    Thank you very much for this! I went through all three of your tutorials and it works! Very happy with it.

Write A Comment