Vue.js + Firebase functionsでお問い合わせフォームを作成する
Vue.js + Firebase functionsでお問い合わせフォームを作成する:
Firebase hosting + Vue.jsでコーポレートサイトを作成する際に困るのが、お問い合わせフォームをどうするかだと思います。
Googleフォームやフォームランなどのフォーム作成サービスを設置するしかないかと思っていたのですが、Firebaseのfunctionsを利用することで、かなり簡単に実装できました。
Fireabse Hostingでホストして、Functionsでメール送信機能を実装するまでをチュートリアル形式で記載します。
以下のようなフォームを作成します。
またここで説明する実装するコードは以下Githubリポジトリで確認できます。
https://github.com/kawamataryo/firebase-send-mail-demo
元なるvueプロジェクトを作成します。選択はデフォルトでOKです。
以下コマンドでlocalhost:8080にアクセスして初期画面が表示されれば準備完了です。
事前にこちらを参考にFirebaseCLIのインストールを行ってください。
Firebase cliでFirebaseの設定を行います。
選択肢ではFunctionsとHostingにチェックを入れます。
Functionsの設定はデフォルトでOKです。
Hostingの選択肢では、dist, yesを入力してください。
プラウザでFireabseコンソールにアクセスしてプロジェクトを作成します。
作成後,先程作ったsendmail-demoにプロジェクトを適応します。
これで下準備は整いました。
functinonsでのメール通知を実現するため、node.jsからメール送信を可能にするモジュールnodemailerを追加します。
今回は送信サーバーとしてgmailを使うので、そのログイン情報、パスワード及び、ページ管理者(問い合わせメールの送信先)の情報を
functionsの環境変変数に追加します
functions内では、以下構文でこれらの環境変数にアクセスできます。
そしてfunctionsのindex.jsに以下を記述し、sendmailというfunctionを作成します。
これでfunctionsの設定は完了です。
最後にクライアント側のForm作成を行います。
フォーム作成で楽をするために、コンポーネントライブラリのVuetifyを使用します。
次にFirebase functionsのクライアントとして使用するため、firebaseのモジュールを追加します。
pluginsディレクトリにFireabaseの初期化用のjsファイルを追加します。
config内の値は、Firebaseのプロジェクトコンソールにて、確認してください。
components配下でformのコンポーネントを作成します。
そして、以下内容を記載します。
次に、App.vueでContactForm.vueを読み込むように設定します。
これでクライアント側の設定は完了です。
ここまででいざデプロイと行きたいところなのですが、gmailをメールサーバーとして使用する場合、安全性の低いアプリのアクセスを有効にする必要があります。
メールサーバーとして利用するGoogleアカウントにログイン後、以下URLにアクセスして、設定を有効にしてください。
https://myaccount.google.com/lesssecureapps
Vueプロジェクトのbuildを行います。実行するとdistディレクトリに実行ファイルが作成されます。
いよいよ最後。
以下コマンドを実行してDeploy complete!が表示されればデプロイ完了です。
Hosting URL:xxxxにアクセスして実際にフォームに送信してみてください。
Firebase本当にすごいですね。ここまで全て無料です。
今後もFireabse Vue.jsで色々作っていきたいです。
Firebase hosting + Vue.jsでコーポレートサイトを作成する際に困るのが、お問い合わせフォームをどうするかだと思います。
Googleフォームやフォームランなどのフォーム作成サービスを設置するしかないかと思っていたのですが、Firebaseのfunctionsを利用することで、かなり簡単に実装できました。
Fireabse Hostingでホストして、Functionsでメール送信機能を実装するまでをチュートリアル形式で記載します。
以下のようなフォームを作成します。
またここで説明する実装するコードは以下Githubリポジトリで確認できます。
https://github.com/kawamataryo/firebase-send-mail-demo
1. プロジェクトの準備
1-1. Vueプロジェクトの作成
元なるvueプロジェクトを作成します。選択はデフォルトでOKです。$ vue create sendmail-demo
$ cd sendmail-demo $ yarn serve
1-2. Firebaseの設定
事前にこちらを参考にFirebaseCLIのインストールを行ってください。Firebase cliでFirebaseの設定を行います。
選択肢ではFunctionsとHostingにチェックを入れます。
$ firebase init ######## #### ######## ######## ######## ### ###### ######## ## ## ## ## ## ## ## ## ## ## ## ###### ## ######## ###### ######## ######### ###### ###### ## ## ## ## ## ## ## ## ## ## ## ## #### ## ## ######## ######## ## ## ###### ######## You're about to initialize a Firebase project in this directory: /Users/kawamataryou/firebase_training/sendmail-demo ? Which Firebase CLI features do you want to setup for this folder? Press Space to select features, then Enter to confirm your choices. ◯ Database: Deploy Firebase Realtime Database Rules ◯ Firestore: Deploy rules and create indexes for Firestore ◉ Functions: Configure and deploy Cloud Functions ❯◉ Hosting: Configure and deploy Firebase Hosting sites ◯ Storage: Deploy Cloud Storage security rules === Project Setup First, let's associate this project directory with a Firebase project. You can create multiple project aliases by running firebase use --add, but for now we'll just set up a default project. ? Select a default Firebase project for this directory: [don't setup a default project]
=== Functions Setup A functions directory will be created in your project with a Node.js package pre-configured. Functions can be deployed with firebase deploy. ? What language would you like to use to write Cloud Functions? JavaScript ? Do you want to use ESLint to catch probable bugs and enforce style? No ? File functions/package.json already exists. Overwrite? No i Skipping write of functions/package.json ? File functions/index.js already exists. Overwrite? No i Skipping write of functions/index.js ? Do you want to install dependencies with npm now? Yes audited 4168 packages in 3.772s found 0 vulnerabilities
=== Hosting Setup Your public directory is the folder (relative to your project directory) that will contain Hosting assets to be uploaded with firebase deploy. If you have a build process for your assets, use your build's output directory. ? What do you want to use as your public directory? dist ? Configure as a single-page app (rewrite all urls to /index.html)? Yes ✔ Wrote dist/index.html i Writing configuration info to firebase.json... i Writing project information to .firebaserc... ✔ Firebase initialization complete!
1-3. Firebaseコンソールでのプロジェクト作成、設定
プラウザでFireabseコンソールにアクセスしてプロジェクトを作成します。作成後,先程作ったsendmail-demoにプロジェクトを適応します。
これで下準備は整いました。
$ firebase use --add send-mail-demo
2. Firebase functionでのメール通知処理の実装
2-1 nodemailerの追加
functinonsでのメール通知を実現するため、node.jsからメール送信を可能にするモジュールnodemailerを追加します。# 1でfirebase functionsの設定を行うとfunctionsディレクトリが自動で作られます。 $ cd functions $ yarn add nodemailer
2-2. 設定ファイルの追加
今回は送信サーバーとしてgmailを使うので、そのログイン情報、パスワード及び、ページ管理者(問い合わせメールの送信先)の情報をfunctionsの環境変変数に追加します
$ firebase functions:config:set gmail.email="メールサーバーとして使うgmailのログインID" gmail.password="メールサーバーとして使うgmailのパスワード" admin.email="問い合わせメールの送信先となるページ管理者のアドレス"
const gmailEmail = functions.config().gmail.email; const gmailPassword = functions.config().gmail.password; const adminEmail = functions.config().admin.email;
2-3. functionの作成
そしてfunctionsのindex.jsに以下を記述し、sendmailというfunctionを作成します。# functionsディレクトリにて $ vi index.js
const functions = require("firebase-functions"); 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.contents} `; }; 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(`admin send failed. ${err}`); } return console.log("admin and user success"); }); });
3. Vue.jsでFormの作成
最後にクライアント側のForm作成を行います。
3-1 fireabse, vuetifyのモジュールを追加
フォーム作成で楽をするために、コンポーネントライブラリのVuetifyを使用します。# プロジェクト直下で。選択肢はデフォルトでOK。 $ vue add vuetify
# プロジェクト直下で $ yarn add firebase
3-2. Firebaseの初期設定
pluginsディレクトリにFireabaseの初期化用のjsファイルを追加します。$ vi src/plugins/firebase.js
import firebase from "firebase"; const config = { apiKey: "xxxxxx", authDomain: "xxxxxx.firebaseapp.com", databaseURL: "xxxxxx.firebaseio.com", projectId: "xxxxxx", storageBucket: "xxxxxx.appspot.com", messagingSenderId: "xxxxxx" }; firebase.initializeApp(config); export const functions = firebase.functions();
3-3. Formコンポーネントの作成
components配下でformのコンポーネントを作成します。$ vi src/components/ContactForm.vue
ContactForm.vue
<template> <div> <v-card> <v-container> <h2>お問い合わせ</h2> <v-form ref="form" v-model="contactFormValidation.valid" lazy-validation> <v-text-field v-model="contactForm.name" :rules="contactFormValidation.nameRules" label="名前" required ></v-text-field> <v-text-field v-model="contactForm.email" :rules="contactFormValidation.emailRules" label="メールアドレス" required ></v-text-field> <v-textarea v-model="contactForm.contents" :rules="contactFormValidation.contentsRules" label="内容" required ></v-textarea> <v-btn :loading="contactForm.loading" :disabled="!contactFormValidation.valid" @click="sendMail()" block large color="info" class="mt-4 font-weight-bold" >送信 </v-btn> </v-form> </v-container> </v-card> <v-snackbar v-model="snackBar.show" :color="snackBar.color" bottom right :timeout="6000" class="font-weight-bold" > {{snackBar.message}} </v-snackbar> </div> </template> <script> import { functions } from '@/plugins/firebase' export default { data: () => ({ contactForm: { name: '', contents: '', email: '', loading: false }, contactFormValidation: { valid: false, nameRules: [v => !!v || '名前は必須項目です'], emailRules: [v => !!v || 'メールアドレスは必須項目です'], contentsRules: [v => !!v || '内容は必須項目です'] }, snackBar: { show: false, color: '', message: '' } }), methods: { sendMail: function () { if (this.$refs.form.validate()) { this.contactForm.loading = true const mailer = functions.httpsCallable('sendMail') mailer(this.contactForm) .then(() => { this.formReset() this.showSnackBar( 'success', 'お問い合わせありがとうございます。送信完了しました' ) }) .catch(err => { this.showSnackBar( 'error', '送信に失敗しました。時間をおいて再度お試しください' ) console.log(err) }) .finally(() => { this.contactForm.loading = false }) } }, showSnackBar: function (color, message) { this.snackBar.message = message this.snackBar.color = color this.snackBar.show = true }, formReset: function () { this.$refs.form.reset() } } } </script>
vi src/App.vue
src/App.vue
<template> <v-app> <v-toolbar app> <v-toolbar-title class="headline text-uppercase"> <span>Vuetify</span> <span class="font-weight-light">MATERIAL DESIGN</span> </v-toolbar-title> <v-spacer></v-spacer> <v-btn flat href="https://github.com/vuetifyjs/vuetify/releases/latest" target="_blank" > <span class="mr-2">Latest Release</span> </v-btn> </v-toolbar> <v-content> <HelloWorld/> </v-content> </v-app> </template> <script> import HelloWorld from './components/HelloWorld' export default { name: 'App', components: { HelloWorld }, data () { return { // } } } </script>
4. メールサーバーの設定・デプロイ
4-1. gmailの設定
ここまででいざデプロイと行きたいところなのですが、gmailをメールサーバーとして使用する場合、安全性の低いアプリのアクセスを有効にする必要があります。メールサーバーとして利用するGoogleアカウントにログイン後、以下URLにアクセスして、設定を有効にしてください。
https://myaccount.google.com/lesssecureapps
4-2. Vueプロジェクトのbuild
Vueプロジェクトのbuildを行います。実行するとdistディレクトリに実行ファイルが作成されます。$ yarn run build
デプロイ
いよいよ最後。以下コマンドを実行してDeploy complete!が表示されればデプロイ完了です。
Hosting URL:xxxxにアクセスして実際にフォームに送信してみてください。
$ firebase deploy === Deploying to 'send-mail-demo'... i deploying functions, hosting i functions: ensuring necessary APIs are enabled... ⚠ functions: missing necessary APIs. Enabling now... ✔ functions: all necessary APIs are enabled i functions: preparing functions directory for uploading... i functions: packaged functions (72.49 KB) for uploading ✔ functions: functions folder uploaded successfully i hosting[send-mail-demo]: beginning deploy... i hosting[send-mail-demo]: found 1 files in dist ✔ hosting[send-mail-demo]: file upload complete i functions: creating Node.js 6 function sendMail(us-central1)... ✔ functions[sendMail(us-central1)]: Successful create operation. Function URL (sendMail): https://us-central1-xxxx.cloudfunctions.net/sendMail i hosting[send-mail-demo]: finalizing version... ✔ hosting[send-mail-demo]: version finalized i hosting[send-mail-demo]: releasing new version... ✔ hosting[send-mail-demo]: release complete ✔ Deploy complete! Project Console: https://console.firebase.google.com/project/send-mail-demo/overview Hosting URL: https://xxxx.firebaseapp.com
感想
Firebase本当にすごいですね。ここまで全て無料です。今後もFireabse Vue.jsで色々作っていきたいです。
コメント
コメントを投稿