Vue.jsのプロジェクトにfirebaseを導入する

Vue.js/Nuxt.js

概要

Vue.jsを利用したプロジェクトに、firestoreを利用してデータ取得を行う手順を解説する。

公式ドキュメント

公式ドキュメントはこちら。

Firestore  |  Firebase
Google Cloud インフラストラクチャ上に構築された、柔軟でスケーラブルな NoSQL クラウド データベースを使用して、クライアント側とサーバー側の開発用のデータを保存および同期します。

前提

  • vue createコマンドを利用して作成したVue.jsプロジェクトを想定する
  • firebaseの登録手順などは割愛し、実装方法にフォーカスする
  • firebaseのバージョンは9系
  • vueのバージョンは3系

実装前のパッケージ構成はこちら。

$ tree . -L 2 -I "node_modules*"
.
├── README.md
├── babel.config.js
├── dist
│   ├── css
│   ├── favicon.ico
│   ├── index.html
│   └── js
├── jsconfig.json
├── package-lock.json
├── package.json
├── public
│   ├── favicon.ico
│   └── index.html
├── src
│   ├── App.vue
│   ├── assets
│   ├── components
│   └── main.js
└── vue.config.js

手順

全体の流れ

  1. firebase用のモジュールを作成し、設定値などを記載する
  2. Vueファイルにて、↑のモジュールをimportして利用する
  3. createdのライフサイクルなどでデータにアクセスする

firebase用のモジュールを作成する

./src/firebase.jsを新規に作成し、firebaseの設定値などを記述する。

import { initializeApp } from "firebase/app";

const firebaseConfig = {
  apiKey: "XXXXXXXXXX",
  authDomain: "XXXXXXXXXX",
  projectId: "XXXXXXXXXX",
  storageBucket: "XXXXXXXXXX",
  messagingSenderId: "XXXXXXXXXX",
  appId: "XXXXXXXXXX",
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);

// Vueファイルでimportできるようにする
export default app;

firebaseにてデータを格納する

firebaseのデータ構造は、今回このように定義した。

vueファイルにて、作成したfirebaseモジュールをインポートして利用する

App.vueの実装は以下の通り。

  1. firebase.jsimport firebase from "@/firebase";でインポート
  2. getFirestore()メソッドを利用してfirestoreへアクセスするためのオブジェクトを作成
  3. 参照するドキュメントパスを指定して、データを取得する
<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <h1>Firebase連携サンプルプロジェクト</h1>
  <p>{{ document }}</p>
</template>

<script>
// アットマークはソースディレクトリのルートを示す
import firebase from "@/firebase";
// firestoreで使うものだけをimport
import { getFirestore, doc, getDoc } from "firebase/firestore";

export default {
  name: "App",
  data() {
    return {
      message: "vue message.",
      document: null,
    };
  },
  async created() {
    // firestoreの初期化を行い、firebaseに接続するための参照を作成する
    const db = getFirestore(firebase);

    // どのドキュメントを参照するか特定する
    const docRef = doc(db, "sample", "document_id");

    // データを取り出す
    const docSnap = await getDoc(docRef);

    if (docSnap.exists()) {
      // データが存在した場合、「document」変数に格納する
      console.log("Document data:", docSnap.data());
      this.document = docSnap.data();
    } else {
      // doc.data() will be undefined in this case
      console.log("No such document!");
    }
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

今回はcreatedのライフサイクルでデータ取得しているが、パフォーマンスなどに応じて適宜変更するのが良い。

結果

「document」変数にデータが格納され、画面に表示される。

まとめ

  • 設定値はfirebase.jsを作成してモジュール化
  • 必要なvueファイルにて、↑をimportして参照するだけ
  • 必要に応じてfirestoreへの接続設定などもモジュールの中に組み込んでも良い

トラブルシューティング

Uncaught (in promise) FirebaseError: Missing or insufficient permissions.

原因

firebaseのデータにアクセスするためのパーミッション設定により、データ取得不可になっている可能性が高い。

解決策(一時的)

※本番環境でやってしまうと誰でもデータを書き換えられるようになってしまうため、リリース時は適切な権限設定に変更すること

本来は認証機能と合わせて利用するのが良いが、
開発時の動作確認などで一時的に認証を通したい場合の解決策は以下の通り。

Cloud Firestoreのルール設定を以下のように変更する。

// 変更前
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

// 変更後
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}
タイトルとURLをコピーしました