😎

Firebase Cloud Firestore + Vueのデータ連携とCRUD機能

に公開

概要

現在開発中の個人サービスにおいて、プロトタイプ化とトライアンドエラーをメインの目的としてVue.js + Firebaseを開発環境で使用しています。
別の活動もあるため自分のペースにはなりますが当初イメージしていたデータ構成や機能イメージの実現性にも変化が出てきたので、今回の記事にまとめようと思います。

参考文献

Firestore側の構成

最終的にフロント側(Vue)での表示、CRUD機能を実装することが必要になるので、まずFirestoreの構成を見てみます。
公式サイトにもありますがFirestoreは「NoSQL ドキュメント指向データベース」というものになるので、MySQLなどの一般的なSQL構造とは似て非なるものと考えた方がいいです。

スクリーンショット 2022-04-19 15.15.38.png
上記キャプチャがSQLの編集画面ですが、

  • 「コレクション」:テーブル群
  • 「ドキュメント」:テーブル
    というイメージになり、これらを取りまとめるDBとして「プロジェクト」単位で定義する形になります。

ドキュメントは追加した際にユニークのドキュメントID(自動採番 or カスタム)が振られ、フロント側でこの値を取得することも可能です。

Firestoreデータの取得

CLIでFirebaseへログイン、連携すると次のような形でフロント側にFirestoreのデータを連携することができるようになります。

src/firebase.js
import firebase from "firebase/compat/app";

// Firestore参照
export const db = firebase.firestore();

複数のコンポーネントで使うパターンがほとんどだと思うので、firebase用のJSファイルを用意して汎用的に使えるようconst関数dbを定義。

src/views/Project/Detail.vue
<script>
// Firebase認証
import { db } from "@/firebase";

export default {
  data() {
    return {
      datas_project: [],
      
    };
  },

  created() {
    // ポートフォリオ
    this.getProjectData();
  },

  methods: {
    // プロジェクト
    getProjectData() {
      console.log(this.$route.query);
      const project_id = this.$route.query.id;

      db.collection("tbl_project")
        .where("project_id", "==", project_id)
        .get()
        .then((snapshot) => {
          snapshot.forEach((doc) => {
            console.log("ドキュメントID: ", doc.id);
            this.datas_project.push(doc.data());
          });
        });
    },
  },
};

画面側のソース一例。
Firebaseデータを扱う各コンポーネントで、先ほど定義したconst関数dbをインポートして使用します。

datas_project: [],

data() ではデータ格納用に「datas_project」を定義します。

db.collection("tbl_project")
  .where("project_id", "==", project_id)
  .get()
  .then((snapshot) => {
    snapshot.forEach((doc) => {
      console.log("ドキュメントID: ", doc.id);
      this.datas_project.push(doc.data());
    });
  });

ドキュメントの参照方法は公式サイトを参照。
上記の記述では、tbl_projectドキュメントを参照後、project_idが特定値であることを条件にフィルタリング。
条件に合ったものをsnapchatでループ処理し、data()内で定義したdatas_projectに格納するという流れになります。

<div v-for="data in datas_project" :key="data">
 {{ data.project_name }}
</div>

あとはこんな感じで、Firestoreで定義したデータ構成をもとに参照できるようになります。

Cloud Firestore にデータを追加する

Vueで作成したフォーム項目→Firestoreへデータを連携し、Firestore側で追加するにはこちらを参照。

https://firebase.google.com/docs/firestore/manage-data/add-data?hl=ja

基本的にはこのような流れになります。

  • コレクションを指定
  • ドキュメントIDを指定(自動で割り振り or 任意名)
  • 入力するデータ項目・参照元を指定
  • set() メソッドを使用(ID指定を省略したadd()メソッドでも可能)

ドキュメントIDはFirestoreの編集ページでこのように表示されます。
ユニークな値になる必要がありますが、指定した場合はその値が、指定なしの場合はランダム文字列で自動生成されます。

スクリーンショット 2022-04-30 11.02.31.png

// Add a new document in collection "cities"
db.collection("cities").doc("LA").set({
    name: "Los Angeles",
    state: "CA",
    country: "USA"
})
.then(() => {
    console.log("Document successfully written!");
})
.catch((error) => {
    console.error("Error writing document: ", error);
});

ドキュメントのソースを解釈するとこのようになります。

  • コレクション名: cities
  • ドキュメント名: LA(任意指定)
  • データ項目: name、state、country

任意指定ではなく自動生成のドキュメントIDを使うにはドキュメント名の指定を外す、またはadd()メソッドを使えばOKです。

db.collection("cities").doc().set({
    name: "Los Angeles",
    state: "CA",
    country: "USA"
})
db.collection("cities").add({
    name: "Los Angeles",
    state: "CA",
    country: "USA"
})

また、これを応用して自動生成IDをIDとして格納したドキュメントを作成する方法もあります。
ドキュメントを取得した際にIDが発行されるので、これを関数として格納するという流れになります。

// 自動発行されるID名を関数化
const newDoc = db.collection("cities").doc().id;
// 取得したID名をドキュメント名、追加項目の「id」として指定
db.collection("cities").doc(newDoc).set({
    id: newDoc,
    name: "Los Angeles",
    state: "CA",
    country: "USA"
})

Cloud Firestore のデータを更新する

ドキュメントを更新する

すでに作成しているドキュメントを更新する場合は update()メソッドを使用します。

var washingtonRef = db.collection("cities").doc("DC");

// Set the "capital" field of the city 'DC'
return washingtonRef.update({
    capital: true
})
.then(() => {
    console.log("Document successfully updated!");
})
.catch((error) => {
    // The document probably doesn't exist.
    console.error("Error updating document: ", error);
});

Discussion