Author: Firebase (https://firebase.google.com)
Description: Composes and sends an email based on the contents of a document written to a specified Cloud Firestore collection.
Details: Use this extension to render and send emails that contain the information from documents added to a specified Cloud Firestore collection.
Adding a document triggers this extension to send an email built from the document's fields. The document's top-level fields specify the email sender and recipients, including to
, cc
, and bcc
options (each supporting UIDs). The document's message
field specifies the other email elements, like subject line and email body (either plaintext or HTML)
Here's a basic example document write that would trigger this extension:
admin.firestore().collection('mail').add({
to: '[email protected]',
message: {
subject: 'Hello from Firebase!',
html: 'This is an <code>HTML</code> email body.',
},
})
You can also optionally configure this extension to render emails using Handlebar templates. Each template is a document stored in a Cloud Firestore collection.
When you configure this extension, you'll need to supply your SMTP credentials for mail delivery. Note that this extension is for use with bulk email service providers, like SendGrid, Mailgun, etc.
When using SendGrid (SMTP_CONNECTION_URI
includes sendgrid.net
), you can assign categories to your emails.
{
"to": ["[email protected]"],
"categories": ["Example_Category"],
"message": {
"subject": "Test Email with Categories",
"text": "This is a test email to see if categories work.",
"html": "<strong>This is a test email to see if categories work.</strong>"
}
}
Add this document to the Firestore mail collection to send categorized emails.
For more details, see the SendGrid Categories documentation.
This section will help you set up OAuth2 authentication for the extension, using GCP (Gmail) as an example.
The extension is agnostic with respect to OAuth2 provider. You just need to provide it with valid Client ID, Client Secret, and Refresh Token parameters.
-
Go to the Google Cloud Console
-
Select your project
-
In the left sidebar, navigate to APIs & Services > Credentials
-
Click Create Credentials and select OAuth client ID
-
Set the application type to Web application
-
Give your OAuth client a name (e.g., "Firestore Send Email Extension")
-
Under Authorized redirect URIs, add the URI where you'll receive the OAuth callback, for example,
http://localhost:8080/oauth/callback
.Note: The redirect URI in your OAuth client settings MUST match exactly the callback URL in your code.
-
Click Create.
- In Google Cloud Console, go to APIs & Services > OAuth consent screen
- Choose the appropriate user type:
- External: For applications used by any Google user
- Internal: For applications used only by users in your organization
Important Note: If your OAuth consent screen is in "Testing" status, refresh tokens will expire after 7 days unless the User Type is set to "Internal."
You can use a standalone helper script (oauth2-refresh-token-helper.js
) that generates a refresh token without requiring any npm installations.
Prerequisites:
- You must have Node.js installed on your machine
Download the script:
-
Download the script using curl, wget, or directly from your browser:
# Using curl curl -o oauth2-refresh-token-helper.js https://raw.githubusercontent.com/firebase/extensions/refs/heads/master/firestore-send-email/scripts/oauth2-refresh-token-helper.js # Using wget wget https://raw.githubusercontent.com/firebase/extensions/refs/heads/master/firestore-send-email/scripts/oauth2-refresh-token-helper.js
You can also view the script on GitHub and download it manually.
Note: If you are creating your own application to obtain a refresh token, in a Node.js environment where you can use npm packages, consider using the official google-auth-library instead:
- Install the library:
npm install google-auth-library
- Then use it like this:
import { OAuth2Client } from "google-auth-library"; // Initialize OAuth client const oAuth2Client = new OAuth2Client(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI); // Generate authorization URL const authorizeUrl = oAuth2Client.generateAuthUrl({ access_type: "offline", prompt: "consent", scope: ["https://mail.google.com/"], // Full Gmail access }); // After receiving the code from the callback: const { tokens } = await oAuth2Client.getToken(code); const refreshToken = tokens.refresh_token;
-
Run the script with Node.js:
node oauth2-refresh-token-helper.js
-
The script supports the following command-line options:
--port, -p Port to run the server on (default: 8080 or PORT env var) --id, -i Google OAuth Client ID --secret, -s Google OAuth Client Secret --output, -o Output file to save the refresh token (default: refresh_token.txt) --help, -h Show help information
-
You can either provide your credentials as command-line arguments or set them as environment variables:
# Using environment variables export CLIENT_ID=your_client_id export CLIENT_SECRET=your_client_secret node oauth2-refresh-token-helper.js # Using command-line arguments node oauth2-refresh-token-helper.js --id=your_client_id --secret=your_client_secret
-
The script will:
- Start a local web server
- Open your browser to the OAuth consent page
- Receive the authorization code
- Exchange the code for tokens
- Save the refresh token to a file (default:
refresh_token.txt
) - Display the refresh token in your browser
-
Important: The redirect URI in the script (
http://localhost:8080/oauth/callback
by default) MUST match exactly what you configured in the Google Cloud Console OAuth client settings. -
The script automatically requests the appropriate scope for Gmail access (
https://mail.google.com/
) and sets the authorization parameters to always receive a refresh token (access_type: "offline"
andprompt: "consent"
).
When installing the extension, select "OAuth2" as the Authentication Type and provide the following parameters:
- OAuth2 SMTP Host:
smtp.gmail.com
(for Gmail) - OAuth2 SMTP Port:
465
(for SMTPS) or587
(for STARTTLS) - Use Secure OAuth2 Connection:
true
(for port 465) orfalse
(for port 587) - OAuth2 Client ID: Your Client ID from GCP
- OAuth2 Client Secret: Your Client Secret from GCP
- OAuth2 Refresh Token: The refresh token generated in Step 3
- SMTP User: Your full Gmail email address
Leave Use secure OAuth2 connection?
as the default value true
.
- Testing Status: If your OAuth consent screen is in "Testing" status, refresh tokens expire after 7 days unless User Type is set to "Internal"
- Solution: Either publish your app or ensure User Type is set to "Internal" in the OAuth consent screen settings
- Problem: If you don't receive a refresh token during the OAuth flow
- Solution: Make sure you've revoked previous access or forced consent by going to Google Account Security > Third-party apps with account access
- Problem: If you see authentication errors, you might not have the correct scopes
- Solution: Ensure you've added
https://mail.google.com/
as a scope in the OAuth consent screen
To use Firestore's TTL feature for automatic deletion of expired email documents, the extension provides several configuration parameters.
The extension will set a TTL field in the email documents, but you will need to manually configure a TTL policy for the collection/collection group the extension targets, on the delivery.expireAt
field.
Detailed instructions for creating a TTL field can be found in the Firestore TTL Policy documentation.
To install an extension, your project must be on the Blaze (pay as you go) plan
- This extension uses other Firebase and Google Cloud Platform services, which have associated charges if you exceed the service’s no-cost tier:
- Cloud Firestore
- Cloud Functions (Node.js 10+ runtime. See FAQs)
Usage of this extension also requires you to have SMTP credentials for mail delivery. You are responsible for any associated costs with your usage of your SMTP provider.
You can find more information about this extension in the following articles:
Configuration Parameters:
-
Firestore Instance ID: The Firestore database to use. Use "(default)" for the default database. You can view your available Firestore databases at https://console.cloud.google.com/firestore/databases.
-
Firestore Instance Location: Where is the Firestore database located? You can check your current database location at https://console.cloud.google.com/firestore/databases.
-
Authentication Type: The authentication type to be used for the SMTP server (e.g., OAuth2, Username & Password.
-
SMTP connection URI: A URI representing an SMTP server this extension can use to deliver email. Note that port 25 is blocked by Google Cloud Platform, so we recommend using port 587 for SMTP connections. If you're using the SMTPS protocol, we recommend using port 465. In order to keep passwords secure, it is recommended to omit the password from the connection string while using the
SMTP Password
field for entering secrets and passwords. Passwords and secrets should now be included inSMTP password
field. Secure format:smtps://[email protected]@smtp.gmail.com:465
(username only)smtps://smtp.gmail.com:465
(No username and password) Backwards Compatible (less secure):smtps://[email protected]:[email protected]:465
. (username and password) -
SMTP password: User password for the SMTP server
-
OAuth2 SMTP Host: The OAuth2 hostname of the SMTP server (e.g., smtp.gmail.com).
-
OAuth2 SMTP Port: The OAuth2 port number for the SMTP server (e.g., 465 for SMTPS, 587 for STARTTLS).
-
Use secure OAuth2 connection?: Set to true to enable a secure connection (TLS/SSL) when using OAuth2 authentication for the SMTP server.
-
OAuth2 Client ID: The OAuth2 Client ID for authentication with the SMTP server.
-
OAuth2 Client Secret: The OAuth2 Client Secret for authentication with the SMTP server.
-
OAuth2 Refresh Token: The OAuth2 Refresh Token for authentication with the SMTP server.
-
OAuth2 SMTP User: The OAuth2 user email or username for SMTP authentication.
-
Email documents collection: What is the path to the collection that contains the documents used to build and send the emails?
-
Default FROM address: The email address to use as the sender's address (if it's not specified in the added email document). You can optionally include a name with the email address (
Friendly Firebaser <[email protected]>
). This parameter does not work with Gmail SMTP. -
Default REPLY-TO address: The email address to use as the reply-to address (if it's not specified in the added email document).
-
Users collection: A collection of documents keyed by user UID. If the
toUids
,ccUids
, and/orbccUids
recipient options are used in the added email document, this extension delivers email to theemail
field based on lookups in this collection. -
Templates collection: A collection of email templates keyed by name. This extension can render an email using a Handlebar template, it's recommended to use triple curly braces
{{{ }}}
in your Handlebars templates when the substitution value is a URL or otherwise sensitive to HTML escaping. -
Firestore TTL type: Do you want the firestore records to be marked with an expireAt field for a TTL policy? If "Never" is selected then no expireAt field will be added. Otherwise you may specify the unit of time specified by the TTL_EXPIRE_VALUE parameter. Defaults to "Never".
-
Firestore TTL value: In the units specified by TTL_EXPIRE_TYPE, how long do you want records to be ineligible for deletion by a TTL policy? This parameter requires the Firestore TTL type parameter to be set to a value other than
Never
. For example, ifFirestore TTL type
is set toDay
then setting this parameter to1
will specify a TTL of 1 day. -
TLS Options: A JSON value representing TLS options. For more information, see https://nodejs.org/api/tls.html#tls_class_tls_tlssocket
Other Resources:
- processQueue (firebaseextensions.v1beta.v2function)
Access Required:
This extension will operate with the following project IAM roles:
- datastore.user (Reason: Allows this extension to access Cloud Firestore to read and process added email documents.)