vue3にfirebaseを導入してメモアプリを作る

# 概要

Composition APIの勉強のためにfirebaseを使ったメモアプリを作成しました。学習の備忘録としてvue3へfirebaseを連携する方法をこちらに残したいと思います。

# 環境
vue: 3.2.16
tailwindcss: 2.2.19
vite: 2.6.4
firebase: 9.4.0

# firebaseのプロジェクトを作成する
こちらの記事を参考に作成。
詳しく書いてあるので今回は省略します。
[firebaseを使ってnuxtのサーバーサイドレンダリングを試す - Qiita](https://qiita.com/gosshys/items/000493a498a0668e0d85)

# srcフォルダ内にfirebase.jsファイルを作成
初期設定はこちら

```jsx
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
const firebaseConfig = {
  apiKey: "ご自身のキーを入力",
  authDomain: "ご自身のキーを入力",
  projectId: "ご自身のキーを入力",
  storageBucket: "ご自身のキーを入力",
  messagingSenderId: "ご自身のキーを入力",
  appId: "ご自身のキーを入力"
};

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

firebaseはバージョン9になって記述方法が大きく変わったので、今回は書き慣れたバージョン8に合わせる設定に変更します。

```jsx
import firebase from 'firebase/compat/app';
import 'firebase/compat/firestore';

const firebaseConfig = {
  apiKey: "ご自身のキーを入力",
  authDomain: "ご自身のキーを入力",
  projectId: "ご自身のキーを入力",
  storageBucket: "ご自身のキーを入力",
  messagingSenderId: "ご自身のキーを入力",
  appId: "ご自身のキーを入力"
};

firebase.initializeApp(firebaseConfig);
const db = firebase.firestore();
export default db;
```

# 【補足】 まず完成形とビューを共有

まず全体ファイルを共有、その後詳細な説明をします。

全体ファイル

```app.vue
<template>
  <Memos />
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import HelloTS from "./components/HelloTS.vue";

export default defineComponent({
  name: 'App',
  components: {
    HelloTS
  }
});

</script>
```

メモ表示用コンポーネント

```Memos.vue
<template>
<div class="p-5">
    <div>
      <p>memo</p>
      <p>メモの合計：{{ countMemoNum }}</p>
    </div>
    <!-- テキスト入力 -->
    <input type="text" class="border" v-model="inputMemo">
    <button class="bg-gray-300 mx-5 p-1" @click="sendMemo()">送信</button>
    <!-- メモ表示 -->
    <div class="py-5 border">
        <div v-for="(memo, index) in memos" :key="index" class="border m-3">
            <div :name="index" class="p-3">{{ memo }}</div>
        </div>
    </div>
  </div>
</template>

<script lang="ts">
import { ref, computed, onMounted } from 'vue';
import db from "../firebase.js";

export default {

    setup(){
        const memos = ref<Array<String>>([]);
        const inputMemo = ref<String>("");

        const sendMemo = (): void => {
            memos.value.push(inputMemo.value);
            inputMemo.value = "";
        }

        onMounted(() => {
            db.collection("memos").get().then((querySnapshot: any) => {
                querySnapshot.forEach((doc: any) => {
                    console.log(doc.data().text);
                    memos.value.push(doc.data().text);
                })
            })
        }) 

        const countMemoNum = computed(() => {
            return memos.value.length;
        })

        return{
            memos,
            inputMemo,
            sendMemo,
            countMemoNum
        }
    },
}
```

<br>

見た目はこんな感じです。
firestoreに保存された「テスト」というテキストデータが表示されている状態です。
![スクリーンショット 2021-11-13 14.42.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230656/a7623aab-657d-eb3b-f290-820fc2a8d64e.png)


# コンポーネント内でfirebase.jsのメソッドをimport

firebaseを使用したいファイルのscript内でfirebase.jsでexport済みのメソッドをimportします。

```Memos.vue
//dbを読み込むことでfirestoreへアクセスできるようになった。
import db from "../firebase.js";
```

あとはこのdbを用いてfirestoreへのアクセスを行います。

# onMountedを用いてページがマウントされるタイミングでfirestoreのデータが読み込まれるようにする

Options APIではmoutedという関数の中に処理を記述していましたが、Composition APIではsetup内にonMountedと記述、その中に処理を書くことで同様の処理が実現できるようです。

今回、TypeScriptで記述しているため引数にany型を付与しています。またsetup内で定義したmemosという空の配列へ値をpushするためにvalueを記述しています。

<br>

なぜvalueが必要なのかについては公式ドキュメントのsetupの説明をご覧ください。
[セットアップ | Vue.js](https://v3.ja.vuejs.org/guide/composition-api-setup.html#%E5%BC%95%E6%95%B0)



```Memos.vue
//setup内に下記を記述

onMounted(() => {
  db.collection("memos").get().then((querySnapshot: any) => {
    querySnapshot.forEach((doc: any) => {
      memos.value.push(doc.data().text);
    })
  })
 })
```

これでfirebase（正確にはfirestore）の記述は完了です。
HTML内でmemos配列を取り出すことでメモを表示できます。