2

I am using Firebase functions with nodemailer to send email from a contact form on my website.

I am on the free plan, and as I understood Gmail API is considered to be a Google service and not general internet request, so it should work fine.

Here is my Typescript code

import * as functions from 'firebase-functions';
import * as nodemailer from 'nodemailer';
import { DocumentSnapshot } from 'firebase-functions/lib/providers/firestore';

export const sendMessage = functions.firestore.document('/emails/{pushKey}').onCreate((snap: DocumentSnapshot) => {

  const form = snap.data();

  const transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
      type: 'OAuth2',
      user: 'myemail@gmail.com',
      clientId: 'xxxxxxxxxxxxx',
      clientSecret: 'xxxxxxxxx',
      refreshToken: 'xxxxxxxxx'
    },
    debug: true
  });

  const mailOptions = {
    from: 'sender@gmail.com',
    to: 'receiver@gmail.com',
    subject: `Message from ${form.name} <${form.email}>`,
    html: form.message
  };

  return transporter.sendMail(mailOptions)
    .then(() => {
      console.log('Email sent.');
    }).catch((err) => {
      console.log(err);
    });
});

However, I get in the console log

  • sendMessage Function execution took 2908 ms, finished with status: 'ok'

  • sendMessage Function returned undefined, expected Promise or value

  • sendMessage Billing account not configured. External network is not accessible and quotas are severely limited. Configure billing account to remove these restrictions

  • sendMessage Function execution started

Am I using any external network here!

The following code works

import * as functions from 'firebase-functions';
import * as nodemailer from 'nodemailer';
import { DocumentSnapshot } from 'firebase-functions/lib/providers/firestore';


const gmailEmail = encodeURIComponent(functions.config().gmail.email);
const gmailPassword = encodeURIComponent(functions.config().gmail.password);
const mailTransport = nodemailer.createTransport(`smtps://${gmailEmail}:${gmailPassword}@smtp.gmail.com`);

export const sendMessage = functions.firestore.document('/emails/{pushKey}').onCreate((snap: DocumentSnapshot) => {

  const form = snap.data();

  const mailOptions = {
    to: 'receiver@gmail.com',
    subject: `Message from ${form.name} <${form.email}>`,
    html: form.message
  };
  return mailTransport.sendMail(mailOptions)
    .then(() => console.log('worked!'))
    .catch(e => console.log(e));
});

But this way is unsecured, and It requires me to allow less secure apps on my Gmail account.

How can I use Gmail and OAuth2 with the free Firebase plan?

Murhaf Sousli
  • 12,622
  • 20
  • 119
  • 185

1 Answers1

-2

So you cannot make outbound requests on the Firebase free plan. You need to upgrade your plan to make outbound requests, and I believe since you are using 'nodemailer' that is the part trying to make an outbound request. Here is another question with comments about upgrading to use a mail service: How can I use nodemailer with Cloud Functions for Firebase?

I believe Firebase also made the Blaze plan free until you go past the quota of the free plan, so it really won't cost anything until you step past the free quota specified in the pricing (https://firebase.google.com/pricing/).

Nicholas Pesa
  • 2,156
  • 2
  • 24
  • 45