FirebaseをNuxt.jsで使ってみたい俺vsNuxtコミュリファレンス

備忘録です。
下のページをそのままやっているだけなので、私の説明より公式のほうが好きだ、というすごい方はこちら↓から。

https://firebase.nuxtjs.org/guide/getting-started/

Firebaseは初期設定済み(「ウェブアプリへのFirebaseの追加」の画面まで進んでいて、apiKey等が手元にある)という前提です。
設定とは…？という方は[こちら](https://firebase.google.com/docs/web/setup?hl=ja#create-project)から

## はうつー？
### 環境
```:開発環境
OS: Windows 11 Pro (OS Build: 22000.613)
Editor: Visual Studio Code v1.67
npm, npx: v8.8.0
node: v16.15.0

--- Package ---
create-nuxt-app: 4.0.0
nuxt: 2.15.8
firebase: 9.8.1
```
```console: 作成時config
--- create-nuxt-app Configs ---
? Project name: NuxtWithFirebase
? Programming language: JavaScript
? Package manager: Npm
? UI framework: None
? Nuxt.js modules: <未選択 Enter>
? Linting tools: <未選択 Enter>
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Server (Node.js hosting)
? Development tools: jsconfig.json (Recommended for VS Code if you're not using typescript)
  ↑ TypeScriptを使っていないVS Code User向け設定
? What is your GitHub username? <GitHub username>
? Version control system: Git
```
yarnは使ったことないので解説できません…

<details><summary>初期設定</summary>

```:npxを入れる
npm install npx --global
```

入れておいて損はないので`--global`でどこでも認識されるようにしています。

```:create-nuxt-appを入れる
npm install create-nuxt-app
```

入ったらcreate-nuxt-appを実行します。

```:create-nuxt-appを実行する
npx create-nuxt-app <Project Name>
```

色々質問されますが、[こちらの記事](https://qiita.com/cheez921/items/fdfd224099f686e3173d)を参考にして設定してみてください。
yarnを使う方法も書いてあります！

```:firebaseを入れる
npm install firebase
npm install @nuxtjs/firebase
```

これで初期インストールは多分おっけー！

</details>

### 実践
フォルダルートの`nuxt.config.js`を開いて、`modules`を探して次のように編集します。
```js:nuxt.config.js
modules: [
    [
      '@nuxtjs/firebase',
      {
        config: { // --- firebaseConfigからコピペ --- //
          apiKey: '<apiKey>',
          authDomain: '<authDomain>',
          projectId: '<projectId>',
          storageBucket: '<storageBucket>',
          messagingSenderId: '<messagingSenderId>',
          appId: '<appId>',
          measurementId: '<measurementId>' // 設定によってはこの行がない
        }, // --- ここまで --- //
        services: {
          auth: true // Authenticationサービスを使うならこの設定
                     // 他のサービス一覧 -> https://firebase.nuxtjs.org/guide/options/#services
        }
      }
    ]
  ],
```

ここで`npm run dev`をしても初期画面が出てくるだけですが、一応導入はできました。

## 実践
入っただけじゃ面白くないので、実装してみましょう。

componentsフォルダにHoge.vueを作って、

 - Firestoreに`「hogehoge」`というコレクションを作る
 - hogehogeコレクションのフィールドの`name`を`「fugafuga」`としてドキュメントを作る
 - fugafugaドキュメントの中に`content`というコレクションを作成する
 - contentコレクション内に、テキストボックスに書いたコンテンツを`msg`フィールドとして書き込む

頭が痛くなりそうですが、図にするとこんな感じです。(名前/種類 という感じです)
```:tree
[Firestore]
   |
   |--- (hogehoge / col)
   |        |
 ～～～  　　|--- (<random ID> / doc) <- ID自体はランダム付与、nameは"fugafuga"
            |       |
          ～～～     | --- (content / col)
                    |          |
                  ～～～        | --- (<random ID> / doc) <- ID自体はランダム付与、msgは「フィールドボックスの値」
                               |
                             ～～～
```
詳しくは[こちら]("https://firebase.google.com/docs/firestore/data-model?hl=ja#collections")を御覧ください。

さて、実装してみます。
まず、ベースとなるテキストボックスと送信用ボタンをつけます。
```js:Hoge.vue
<template>
  <div>
    <input v-model="formData" />
    <button @click="send">送信</button>
  </div>
</template>

<script>
import { getFirestore, collection, addDoc } from "firebase/firestore";

export default {
  data() {
    return {
      formData: "",
    };
  },
  methods: {
    async send() {
      const db = await getFirestore(); // Firestoreのルートを持ってくる
      const hogeColRef = await collection(db, "hogehoge"); // hogehogeコレクションができる
      const fugaDocRef = await addDoc(hogeColRef, { name: "fugafuga" }); // nameというフィールド(値はfugafuga)を持つドキュメントができる
      const contColRef = await collection(fugaDocRef, "content"); // contentコレクションができる
      const msgRef = await addDoc(contColRef, { msg: this.formData }); // msgというフィールド(値はformData)を持つドキュメントができる

      this.formData = ""; // キレイにする
    },
  },
};
</script>

<style>
</style>

```

めちゃくちゃ簡易的ですが、とりあえず書いてみました。
sendメソッドにasyncを使っている理由として、こんなことが起きる可能性があるからです。
```:事故例
dbを取得する <-ここまではok
fugaDocRefのaddDocが先に動いてしまったが、hogeColRefのcollectionはまだ動いてないのでエラーが発生する。
```
エラー回避のためにasync-awaitを使っていますが、合ってるのかわかりません。(教えて詳しい人)

で、sendメソッド、ぐちゃぐちゃしていて見づらいので、以下のように書くこともできます。
```js:簡単に書いたもの
const db = await getFirestore(); // 変わらない
const fugaDocRef = await addDoc(collection(db, "hogehoge"), { name: "fugafuga" }); // hogehogeとfugafugaができる
const msgRef = await addDoc(collection(fugaDocRef, "content"), { msg: this.formData }); // contentとメッセージ用docができる
```

これ以上まとめると逆に見づらいと思います。

---機能達---
`getFirestore`は名前の通り、Firestoreのルートを持ってきてくれます。
`collection`はコレクションを作成(参照)します。
`addDoc`はコレクションに対してランダムなIDを付与して、ドキュメントを作成します。
詳しくは[こちら](https://firebase.google.com/docs/firestore/manage-data/add-data)

setDocを使う方法が思いつかなかったので実装出来てないのですが、多分ある…

## 〆
Firebase(Firestore)を使う方法を備忘録にしました。
[YUMEMI杯](https://qiita.com/tos-up/items/0b783c87dadb905b01c1)のときに、onSnapshotあたりで辛くなった記憶があるので、これはまた別の記事にしようと思います。
(というかNuxtで実装してないので自分で実装して納得しようと思います)

ではまた宜しくお願いします。

参考
[Firebase Firestore(v9)とNuxtでデータを操作する]("https://t8.dev/ja/blog/firebase_firestore_nuxtjs/")