FirebaseのアプリでSendGridを使ったメール配信機能を実現する


サービス開発をしているとユーザのアクションによってメールを送信することはよくあると思います。
今回はバックエンドにFirebaseを使っているときに登録会員にメール送信をする方法をまとめました。

※ 今回はSendGridを利用します。
※ Amazon SES や Mailgun を利用する場合はメール送信部分を書き換えてください。

目次

  • 全体の流れ
  • Firestoreへのデータ登録時にCloud Functions を実行する
  • Cloud Functions でメールサーバーにリクエストを送る
  • Firestoreのデータをもとにメールの内容を構築する
  • Firebase Authentication から会員情報を取得する

全体の流れ

Firestoreの登録イベント時にCloud Functionsを実行する

Firestoreへのデータ登録時にCloud Functionsを起動するにはindex.jsを以下のようにしてデプロイすると実現できます。

import * as functions from 'firebase-functions';

export const sendInquiryMail = functions.firestore
  .document('examples/{id}')
  .onCreate(async (snap, context) => {
    // 処理を記述
  }

firebaseの初期設定は割愛しています。

firebase deploy

Cloud Functions でメールサーバーにリクエストを送る

SendGridを使う場合はAPI Keyを使う必要があります。
API KeyはSendGridの管理者画面で作成できます。

API Keyは環境ごとに切り替えたいことや、カード管理したくないためFirebaseの環境データに保存しましょう。

firebase functions:config:set sendgrid.apikey="xxxx"

設定した環境データをもとにSendGridのAPIを呼び出します。

const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(functions.config().sendgrid.apikey); // 設定した環境データを取得

// メール送信
const msg = {
  to: '[email protected]',
  from: '[email protected]',
  subject: 'example subject',
  text: 'example body',
};
await sgMail.send(msg);

これでメール送信処理を実現できました。

Firestoreのデータをもとにメールの内容を構築する

メール送信するときには、関連するデータをもとにメールの内容を作ることがあります。

FirebaseのAdminSDKを使って登録データ以外のデータを取得することができます。

const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
const colRef = db.collection('other');
const snapshots = await colRef
  .where('id', '==', 'xxxx')
  .limit(1)
  .get();
const other = snapshots.docs[0].data();

Firebase Authentication から会員情報を取得する

await admin
  .auth()
  .getUser('xxxx')

最終的に以下のようなコードでメール送信を実現できました。


import * as functions from 'firebase-functions';

export const sendInquiryMail = functions.firestore
  .document('examples/{id}')
  .onCreate(async (snap, context) => {
    const admin = require('firebase-admin');
    admin.initializeApp();
    const db = admin.firestore();

    const data = snap.data();

    const user await admin
      .auth()
      .getUser(data.user_id)

    const colRef = db.collection('other');
    const snapshots = await colRef
      .where('id', '==', data.other_id)
      .limit(1)
      .get();
    const other = snapshots.docs[0].data();
    const sgMail = require('@sendgrid/mail');
    sgMail.setApiKey(functions.config().sendgrid.apikey);
    const msg = {
      to: user.email,
      from: '[email protected]',
      subject: 'example subject',
      text: `example body. ${other.body}`,
    };
    await sgMail.send(msg);
  });