Help us understand the problem. What is going on with this article?

Nuxt v2とFirebase(CloudFirestore)でPWA対応Webアプリ開発

福岡から世界中の"むずかしい"を簡単にする株式会社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の機能を利用することで、認証、ストレージの管理、データベースの管理など、従来サーバーサイドで開発していたロジックなしにアプリケーションの開発が可能です。
スクリーンショット 2018-10-13 17.29.02.png
↓↓↓↓↓
スクリーンショット 2018-10-13 17.29.26.png

Firebase使ってみた
Firebase公式

PWA

PWA = Progressive Web Apps(プログレッシブウェブアプリ)のことで、アプリのリンクをホーム画面に残しておくことで、あたかもネイティブアプリケーションのように動作可能なWebアプリケーションのことを言います。
オフラインでも動作可能で、PUSH通知も可能です。

はじめてのプログレッシブ ウェブアプリ

Nuxt v2とFirebase(CloudFirestore)でPWA対応Webアプリ開発

ここからが本題です!
ソースはGithubにあげています。

今回作ったアプリ

Nuxt v2とFirebaseを使ってPWA対応の簡易リアルタイムチャットWebアプリを作ります。
nuxt2_chat.mov.gif

フォルダ構成

フォルダ構成は以下のようになります。
実際のフォルダの場所は開発環境に合わせて読み替えてください。

~
 ∟ 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アプリケーションが表示されます。
スクリーンショット 2018-10-12 18.00.12.png

Firebaseの設定

Firebaseのサイトから新規プロジェクトを作成します。
Firebaseサイト

「プロジェクトを追加」をクリックして、プロジェクト名を入力して、「プロジェクトを作成」をクリックします。
プロジェクトを追加

Firebaseには色々な機能が用意されていますが、今回利用するのは、

  • Authentication
  • Database(Cloud Firestore)
  • Hosting

の3つです。

Firebaseコンソールトップの「開始するにはアプリを追加してください」の上の「</>」をクリックして、アプリから接続するための情報を取得します。
Firebase接続情報
この値は後ほど使います。

Authentication

Authenticationに遷移して、「ログイン方法を設定」をクリックします。
スクリーンショット 2018-10-12 18.18.53.png
「メール/パスワード」でのログインを有効にします。
スクリーンショット 2018-10-12 18.19.23.png
テスト用にユーザーを追加します。
スクリーンショット 2018-10-12 18.23.55.png

Cloud Firestore

Firebaseのデータベースには、Realtime DatabaseとCloud Firestore(β版)の2つがありますが、今回はCloud Firestoreを利用します。

セキュリティルールは後から編集できますが、ひとまず「テストモードで開始」を選択します。
スクリーンショット 2018-10-12 18.41.42.png

Hosting

Hostingに遷移して、「使ってみる」をクリックします。
スクリーンショット 2018-10-12 18.43.37.png

ローカルにFirebaseの開発環境を作る

firebase-toolsをインストールします。

$ cd ~/firebase_app
$ npm install -g firebase-tools

プロジェクトを初期化します。

$ firebase init

Hostingを選択します。
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キーなど接続情報を記述します。

/.env
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との接続情報を取得し、初期化します。

/plugins/firebase.js
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に以下のファイルを作成します。

/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を読み込むよう、以下の設定を追加します。

/nuxt.config.js
  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
/nuxt.config.js
modules: [
  '@nuxtjs/dotenv',
  '@nuxtjs/pwa'
],
manifest: {
  name: '<アプリ名>',
  short_name: '<アプリ略称>',
  lang: 'ja'
},
/.gitignore
# Service Worker
sw.*

Firebase Hostingにデプロイ

Nuxtプロジェクトをgenerateします。

$ cd ~/firebase_app/nuxt2_chat
$ yarn run generate

generateしたファイルをFirebase Hostingにデプロイします。

$ cd ~/firebase_app
$ firebase deploy

スマホからアクセスすると、以下のようにホームに追加するためのナビゲーションが表示されます。
スマホ表示1
スマホ表示2

ホームに追加したアイコンから起動すると、ブラウザのバーが非表示になり、ネイティブアプリのように利用することができます。
スマホ表示1

さらに、オフライン時でもエラーになることなく、画面からメッセージの投稿が可能です。
投稿したメッセージは再びオンラインになった時に自動的にサーバーに送信されます。

プッシュ通知

Webアプリケーションへのプッシュ通知について、以下の記事にまとめました!
NuxtでPWA対応WebアプリにOneSignalからプッシュ通知を送る

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away