【Next.js】メールフォームをFirebase Functionsで実装
今回は、Next.jsとFirebase Functionsを用いて、お問い合わせフォームを実装していきます。
参考にした記事
作成にあたっては以下の2記事が非常に参考になりました。
Vue.js + Firebase functionsでお問い合わせフォームを作成する - Qiita
[firebase] Cloud Functionsを利用したお問い合わせ機能の実装 [react.js] - Qiita
Firebase側の実装
Firebaseとの接続を行います。
lib/db.js
import firebase from 'firebase/app' import 'firebase/firestore' import "firebase/auth"; let db; try { const config = { apiKey : xxxxxxxxxxxxxxxxxxxx, authDomain : xxxxxxxxxxxxxxxxxxxx, databaseURL : xxxxxxxxxxxxxxxxxxxx, projectId : xxxxxxxxxxxxxxxxxxxx, storageBucket : xxxxxxxxxxxxxxxxxxxx, messagingSenderId: xxxxxxxxxxxxxxxxxxxx, appId : xxxxxxxxxxxxxxxxxxxx }; if (!firebase.apps.length) { firebase.initializeApp(config); } // Firestoreインスタンスを作成 db = firebase.firestore(); } catch (error) { console.log(error); } let auth = firebase.auth(); const firestore = firebase.firestore(); module.exports = { // 本来、initializeAppによる初期化は一度きりのため、 // 初期化の結果のみを切り出してexportする db, auth, firebase, firestore };
Firerbase接続に関して、詳しくは以下をご覧ください。
nekorokkekun.hatenablog.com
Firebase Functionsの設定
ルートディレクトリにfunctionsディレクトリを作成します。
次にメーラーをインストールしましょう。
$ yarn add nodemailer $ yarn install
そして、Firebase Functionsの環境変数に、問い合わせを受信するメールアドレスやパスワード、管理者のメールアドレスを設定しましょう。
$ firebase functions:config:set gmail.email="xxxxxx@gmail.com" gmail.password="xxxxxx" admin.email="xxxxxx@gmail.com"
最後にFirebase Functionsを実装します。
functions/index.js
const nodemailer = require("nodemailer"); const gmailEmail = functions.config().gmail.email; const gmailPassword = functions.config().gmail.password; const adminEmail = functions.config().admin.email; // メールサーバー設定 const mailTransport = nodemailer.createTransport({ service: "gmail", auth: { user: gmailEmail, pass: gmailPassword } }); // 管理者用のメールテンプレート const adminContents = data => { return `以下内容でホームページよりお問い合わせを受けました。 お名前: ${data.name} メールアドレス: ${data.email} 内容: ${data.content} `; }; exports.sendMail = functions.https.onCall((data, context) => { // メール設定 let adminMail = { from: gmailEmail, to: adminEmail, subject: "ホームページお問い合わせ", text: adminContents(data) }; // 管理者へのメール送信 mailTransport.sendMail(adminMail, (err, info) => { if (err) { return console.error(`send failed. ${err}`); } return console.log("send success."); }); });
最後に実装したFirebase FunctionsをFIrebaseにデプロイします。
$ yarn deploy
フロント側の実装
以下の記事からそのままお借りしました。
[firebase] Cloud Functionsを利用したお問い合わせ機能の実装 [react.js] - Qiita
import React, { Component } from 'react'; import TextField from '@material-ui/core/TextField'; import Button from '@material-ui/core/Button' import {firebase} from '../lib/db.js'; require("firebase/functions"); class ContactForm extends Component { constructor(){ super() this.onSubmit = this.onSubmit.bind(this) } onSubmit(e){ e.preventDefault() let data = {} data.name = e.target.name.value data.email = e.target.email.value data.content = e.target.content.value let sendMail = firebase.functions().httpsCallable('sendMail'); sendMail(data) e.target.name.value = "" e.target.email.value = "" e.target.content.value = "" e.target.value = "" } render() { const textFieldStyle = { display: "flex", width: "300px", } const contactForm = { display: "flex", flexDirection: "column", alignItems: "center", marginTop: "100px", } return ( <React.Fragment> <div style={contactForm}> <h2>お問い合わせ</h2> <form onSubmit={this.onSubmit}> <TextField name="name" label="お名前" type="text" required style={textFieldStyle} /> <TextField name="email" label="メールアドレス" type="mail" required style={textFieldStyle} /> <TextField required name="content" label="お問い合わせ内容" multiline rows="8" margin="normal" variant="outlined" style={textFieldStyle} /> <Button variant="contained" color="primary" type="submit" style={textFieldStyle} > 送信 </Button> </form> </div> </React.Fragment> ) } } export default ContactForm
これで実際に、設定したメールアドレスへ問い合わせたメールの内容が届くはずです。
Firebase Functionsにエラーが出る場合
以下のようなエラーが出て悩まされました。
send failed. Error: Invalid login: 534-5.7.14 <https://accounts.google.com/signin/continue?sarp=1&scc=1&plt=xxxxxxxxxxx> Please log in via your web browser and then try again. Learn more at https://support.google.com/mail/answer/78754 h16sm1466164ilq.18 - gsmtp
私の場合は、以下のリンクを踏み、アクセスを有効にすることで、メールが届くようになりました。
accounts.google.com