福岡から世界中の"むずかしい"を簡単にする株式会社diffeasyCTOの西@_takeshi_24です。
公開から1年以上が経ち、この記事の内容も少し古くなってきました。
Nuxt.jsやFirebaseを使って、サーバーレスでWebアプリケーションを開発する手順について、アドベントカレンダー「diffeasyCTO西の24(にし)日連続投稿チャレンジ Advent Calendar 2019」の中で、「Nuxt.jsとFirebaseとCloudFunctionsでWebアプリ開発」シリーズとして、連載していきます。
Nuxt.jsとFirebaseなどを使ってWebアプリケーション開発にチャレンジしたい方、是非Qiitaアカウントかtwitterをフォローしていただき、ツッコミやいいね!お願いします!
言葉の説明
まずはNuxt、Firebase、PWAの説明です。
ご存知の方はすっ飛ばしてください!
Nuxt
Vue.js アプリケーションを構築するためのフレームワークです。
こちらの記事に少し詳しく、公式ドキュメントにさらに詳しい情報が載っていますので、そちらをご覧ください。
2018年9月21日にVer2がリリースされました。
Firebase
Googleが提供するBaaS(Backend as a Service)です。
Webフロントエンド、ネイティブアプリからFirebaseの機能を利用することで、認証、ストレージの管理、データベースの管理など、従来サーバーサイドで開発していたロジックなしにアプリケーションの開発が可能です。
↓↓↓↓↓
PWA
PWA = Progressive Web Apps(プログレッシブウェブアプリ)のことで、アプリのリンクをホーム画面に残しておくことで、あたかもネイティブアプリケーションのように動作可能なWebアプリケーションのことを言います。
オフラインでも動作可能で、PUSH通知も可能です。
Nuxt v2とFirebase(CloudFirestore)でPWA対応Webアプリ開発
ここからが本題です!
ソースはGithubにあげています。
今回作ったアプリ
Nuxt v2とFirebaseを使ってPWA対応の簡易リアルタイムチャットWebアプリを作ります。
フォルダ構成
フォルダ構成は以下のようになります。
実際のフォルダの場所は開発環境に合わせて読み替えてください。
~
∟ firebase_app
∟ nuxt2_chat
Nuxt v2でアプリ開発
npmを使って構築もできますが、今回はyarnを使って、scaffoldingツールでNuxtアプリケーションを構築します。
$ cd ~
$ mkdir ./firebase_app
$ cd ./firebase_app
$ yarn create nuxt-app nuxt2_chat #nuxt2_chatはアプリ名
アプリ名や各種フレームワーク、ツールの利用を問われますので、必要に応じて選択します。
? Project name <アプリ名>
? Project description <アプリ説明>
? Use a custom server framework none #サーバーフレームワークは指定しない
? Use a custom UI framework vuetify #UIフレームワークはvuetifyを利用
? Choose rendering mode Single Page App #SPAモードを指定
? Use axios module no #axiosを利用
? Use eslint yes #eslintを利用
? Use prettier yes #prettierを利用
? Author name <作成者名>
? Choose a package manager yarn #yarnでパッケージ管理
・・・
success Saved lockfile.
✨ Done in 32.75s.
今回はテンプレートエンジンにpugを使うので、pugとpug-plain-loaderをインストールします。
※Nuxt v1ではpug-loaderでしたが、v2ではpug-plain-loaderを利用する必要があります。
$ cd ~/firebase_app/nuxt2_chat
$ yarn add pug pug-plain-loader --dev
開発用のサーバーを立ち上げます。
$ yarn run dev
http://localhost:3000
にアクセスすると、Vuetifyが適用されたNuxtアプリケーションが表示されます。
Firebaseの設定
Firebaseのサイトから新規プロジェクトを作成します。
「プロジェクトを追加」をクリックして、プロジェクト名を入力して、「プロジェクトを作成」をクリックします。
Firebaseには色々な機能が用意されていますが、今回利用するのは、
- Authentication
- Database(Cloud Firestore)
- Hosting
の3つです。
Firebaseコンソールトップの「開始するにはアプリを追加してください」の上の「>」をクリックして、アプリから接続するための情報を取得します。
この値は後ほど使います。
Authentication
Authenticationに遷移して、「ログイン方法を設定」をクリックします。
「メール/パスワード」でのログインを有効にします。
テスト用にユーザーを追加します。
Cloud Firestore
Firebaseのデータベースには、Realtime DatabaseとCloud Firestore(β版)の2つがありますが、今回はCloud Firestoreを利用します。
セキュリティルールは後から編集できますが、ひとまず「テストモードで開始」を選択します。
Hosting
ローカルにFirebaseの開発環境を作る
firebase-toolsをインストールします。
$ cd ~/firebase_app
$ npm install -g firebase-tools
プロジェクトを初期化します。
$ firebase init
先ほど作成したFirebaseのプロジェクトを選択します。
? Select a default Firebase project for this directory: nuxt2-chat (nuxt2-chat)
公開するフォルダを指定します。
先ほど作成したNuxtプロジェクトのdistを選択します。
? What do you want to use as your public directory? (public) nuxt2_chat/dist
NuxtとFirebaseを連携
NuxtとFirebaseとの連携にvuexfireを利用します。
Firebaseの接続情報はソース管理から外したいので、.envを利用します。
$ yarn add @nuxtjs/dotenv firebase vuexfire@next --save
※2018年10月12日時点では、vuexfireではCloud Firestoreのbindでエラーになったので、vuexfire@nextをインストールしています。
.envファイルにFirebaseのAPIキーなど接続情報を記述します。
FB_API_KEY=<FirebaseAPIキー>
FB_AUTH_DOMAIN=<Firebse プロジェクトID>.firebaseapp.com
FB_DATABASE_URL=https://<Firebse プロジェクトID>.firebaseio.com
FB_PROJECTID=<Firebse プロジェクトID>
FB_STORAGE_BUCKET=<Firebse プロジェクトID>.appspot.com
FB_MESSAGING_SENDER_ID=<Firebase messaging 通知送信キー>
plugins/firebase.jsでFirebaseとの接続情報を取得し、初期化します。
import firebase from 'firebase'
var config = {
apiKey: process.env.FB_API_KEY,
authDomain: process.env.FB_AUTH_DOMAIN,
databaseURL: process.env.FB_DATABASE_URL,
projectId: process.env.FB_PROJECTID,
storageBucket: process.env.FB_STORAGE_BUCKET,
messagingSenderId: process.env.FB_MESSAGING_SENDER_ID
}
if (!firebase.apps.length) {
firebase.initializeApp(config)
}
export default firebase
Firebaseの認証機能を利用するため、plugins.auth.jsに以下のファイルを作成します。
import firebase from '~/plugins/firebase'
function auth() {
return new Promise((resolve, reject) => {
firebase.auth().onAuthStateChanged(user => {
resolve(user || false)
})
})
}
export default auth
nuxt.config.jsでplugins/firebase、plugins/authと.envを読み込むよう、以下の設定を追加します。
plugins: [
'@/plugins/firebase',
'@/plugins/auth'
],
modules: [
'@nuxtjs/dotenv'
],
認証処理
auth.signInWithEmailAndPassword
(data['email'], data['password'])
.then((user) => {
// ログイン成功
commit('setUser', user)})
.catch((error) => {
// エラー処理
})
Firestoreに書き込み
import 'firebase/firestore'
const db = firebase.firestore()
const messagesRef = db.collection('messages')
export const state = () => ({
messages: [],
})
export const actions = {
addMessageRef: firebaseAction((context, data) => {
messagesRef.add({
uid: data.uid,
text: data.text,
time: Date.now()
})
})
}
Firestoreから読み込み
import 'firebase/firestore'
const db = firebase.firestore()
const messagesRef = db.collection('messages')
export const state = () => ({
messages: [],
})
export const actions = {
initMessages: firebaseAction(async ({ bindFirebaseRef }) => {
await bindFirebaseRef('messages', messagesRef.orderBy('time', 'desc'))
})
}
詳細なソースはGithubにあげていますので、そちらをご覧ください!
PWA対応
PWA対応することで、スマホホーム画面にアプリを追加するように促してくれます。
ホームにアプリを追加するときのアイコン画像を
/static/icon.png
に置きます。
yarn add @nuxtjs/pwa --save
modules: [
'@nuxtjs/dotenv',
'@nuxtjs/pwa'
],
manifest: {
name: '<アプリ名>',
short_name: '<アプリ略称>',
lang: 'ja'
},
# Service Worker
sw.*
Firebase Hostingにデプロイ
Nuxtプロジェクトをgenerateします。
$ cd ~/firebase_app/nuxt2_chat
$ yarn run generate
generateしたファイルをFirebase Hostingにデプロイします。
$ cd ~/firebase_app
$ firebase deploy
スマホからアクセスすると、以下のようにホームに追加するためのナビゲーションが表示されます。
ホームに追加したアイコンから起動すると、ブラウザのバーが非表示になり、ネイティブアプリのように利用することができます。
さらに、オフライン時でもエラーになることなく、画面からメッセージの投稿が可能です。
投稿したメッセージは再びオンラインになった時に自動的にサーバーに送信されます。
プッシュ通知
Webアプリケーションへのプッシュ通知について、以下の記事にまとめました!
NuxtでPWA対応WebアプリにOneSignalからプッシュ通知を送る