takeda_san’s blog

KotlinとVRを頑張っていく方向。

Firebaseで業務アプリケーションを構築しよう 3:一覧画面と編集画面の追加、CloudStoreにデータの保存

シリーズ

前回のあらすじ

Nuxt.jsのアプリケーションをFirebase Functions&Hostingにデプロイして動作確認をしました。
Firebaseで業務アプリケーションを構築しよう 2:Firebase Functions&Hostingにデプロイと動作確認 - takeda_san’s blog

一覧と編集画面を作る

業務システムにありがちな一覧と編集画面のモックを作りましょう。
今回はUI部品にElementをつかってサクサクっと作っていきます。

一覧画面
f:id:takeda_san:20191121231220p:plain

編集画面
f:id:takeda_san:20191121231238p:plain

色々と荒々しいですが、こんなもんでしょう。
ここまでの変更点はこちら。

Add list and edit component · takedasan/yukito@eca4f22 · GitHub

CloudStoreからデータを取得する

次はベタ書きしてあるデータ部分をCloudStoreにつなげてそこから取得するようにします。

firebaseとvuexfireの追加

FirebaseのライブラリとFireStoreとの同期をお手軽にできるライブラリVuefireを追加します。
VuefireのGetting startedに沿ってライブラリを追加します。

Getting Started | Vuefire

npm install vuefire firebase

データベースとの接続設定

plugins配下にfirebase.tsを追加して、下記を書き込みます。
チュートリアルのままだと型チェックで怒られるのでちょっと変えてます。

Getting Started | Vuefire

import firebase from 'firebase/app'
import 'firebase/firestore'

const firebaseInstance = !firebase.apps.length
  ? firebase.initializeApp({ projectId: 'your-project-id' })
  : firebase.app()
const db = firebaseInstance.firestore()
const { Timestamp, GeoPoint } = firebase.firestore

export { Timestamp, GeoPoint }
export { db }

データの追加

編集画面のコンポーネントにデータ追加の処理を追加します。
contract-employeesというコレクションにデータを追加するメソッドを保存ボタンのアクションに設定します。

  methods: {
    onSave() {
      const contractEmployees = db.collection('contract-employees')
      contractEmployees.add(this.contractEmployee)
    }
  }

f:id:takeda_san:20191202224649p:plain

こんな感じでFireStoreのコンソールからコレクションに格納されていることが確認できると思います。
(保存ボタン連打すると無限に増えていくのは見逃してほしい…)

f:id:takeda_san:20191202224506p:plain

変更差分はこちら
firestoreとの接続 · takedasan/yukito@abf5cdf · GitHub

データの一覧

一覧画面のコンポーネントのデータをFireStoreと同期するように設定します。
storeにファイルを追加して、FireStoreのコレクションとバインドすることでデータが同期するようにします。

import { firestoreAction } from 'vuexfire'
import { db } from '@/plugins/firebase'

interface PersonList {
  contractEmployees: ContractEmployee[]
}

export const state: () => PersonList = () => ({
  contractEmployees: []
})

export const getters = {
  getContractEmployees: (state: any) => state.contractEmployees
}

export const actions = {
  bindContractEmployees: firestoreAction(({ bindFirestoreRef }) => {
    return bindFirestoreRef(
      'contractEmployees',
      db.collection('contract-employees')
    )
  })
}

firestoreとの接続 · takedasan/yukito@abf5cdf · GitHub

つぎにコンポーネントのdataの代わりに、このgetterを呼び出します。

import Vue from 'vue'
import { mapGetters } from 'vuex'

export default Vue.extend({
  computed: {
    ...mapGetters({
      contractEmployees: 'person/list/getContractEmployees'
    })
  },
  async asyncData({ store }) {
    await store.dispatch('person/list/bindContractEmployees')
  }
})

こんな感じで、先ほど編集画面で追加したデータが取得できていることが確認できると思います。
また、編集画面での追加がリアルタイムに一覧画面に反映されています。

f:id:takeda_san:20191202225328p:plain

ここまでで基本の一覧画面と編集画面の作成が(すんごい不親切なつくりだが)できました。

差分はこちら
firestoreとの接続 · takedasan/yukito@abf5cdf · GitHub

次回

デプロイフローの構築をします。
ちょっとお勉強がてらGitHub Actionsを使うかもしれないし、いつものCircleCIかもしれない。

takeda-san.hatenablog.com