FirestoreとNuxt.jsで掲示板を作成しようとして失敗した話

---
FirebaseとCloud Firestoreの基本を学習したので、
Vue.jsを使ってリアルタイムで更新される某チャンネル掲示板風のページを作ってみようとして、

前段も前段、Firestoreへの読み込み／書き込みの部分で**失敗した記事**です。

なので一番やりたかった既存ページを再現するCSSコーディング（写経と読んでいます）すらできませんでした。

身の有る記事を読みたいほとんどの方には読む価値ない記事ですが、
Nuxt.jsアプリの簡単な立ち上げ方やホスティング先としてのFirabaseの使い勝手の良さは少しだけ含んでいます。（その辺りまでは楽しいしすごく簡単だったのに・・・）


**出来損ない(GitHub)**
https://github.com/RatchoTetsugaku/practice-Nuxt_firestore_BBS

##概要

* node.js 12.3.1
* Nuxt.js 2.0.0
* Firebase
* Cloud Firestore

##環境構築

###Nuxt.js環境
今回は学習がてらVue.jsのフレームワークとして一番メジャーなNuxt.jsを使用します。
他フレームワークの例に漏れずNuxtもcreate-***-appがあるので、npxを使って有難く使わせて頂きます。

```bash
$ npx create-nuxt-app <project_directory> 

$ ## 対話形式で以下の通り設定
✨  Generating Nuxt.js project in <project_directory>/
? Project name <project_directory>
? Project description My bedazzling Nuxt.js project
? Author name
? Choose the package manager Npm
? Choose UI framework Vuetify.js ## 今回はVuetifyにチャレンジ
? Choose custom server framework None (Recommended)
? Choose Nuxt.js modules Axios ## 念の為
? Choose linting tools
? Choose test framework None
? Choose rendering mode Single Page App ## 超簡易なのでSPAです
? Choose development tools (Press <space> to select, <a> to toggle all, <i> to invert selection)
```

```bash
$ cd <project_directory>
$ npm run dev
```

`http://localhost:3000`でテストアプリが立ち上がります。



###Firebaseプロジェクト作成

次に[Firebase Console](https://firebase.google.com/?hl=ja)でプロジェクトを追加します。
（無料枠ではプロジェクト追加上限は5件らしいので、私は既に作成していたプロジェクトを再利用…）

詳細は公式ドキュメントをご参考にどうぞ。
https://docs.kii.com/ja/samples/push-notifications/push-notifications-android-fcm/create-project


###NuxtとFirebaseを接続

Firebaseの設定やデプロイに利用するので`firebase-tools`をインストールしておきます。

```terminal
$ npm i -g firebase-tools
$ firebase login
```

`firebase login`するとgoogleアカウントの選択画面が表示されるので、使用するアカウントを選択してアクセス許可をします。
次にrootディレクトリのまま以下を実行します。

```terminal
$ firebase init
```

対話形式で以下のように設定します（何か間違っているかも・・・）

```bash
? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. 
## Firestore: Deploy rules and create indexes for Firestore,
## Hosting: Configure and deploy Firebase Hosting sites
```

```bash
? Please select an option: ## Use an existing project
```

```bash
? What file should be used for Firestore Rules? ## firestore.rules
```

```bash
? What file should be used for Firestore indexes? ## firestore.indexes.json
```

```bash
## 重要！
? What do you want to use as your public directory? ## dist
```

```bash
? Configure as a single-page app (rewrite all urls to /index.html)? ## No
```

###env設定

init後は、自動で`dist/`にfirebase標準ファイル群が作成されています。

次に`@nuxtjs/dotenv`を使ってFirebaseの接続情報を`.env`ファイルから読み込めるようにしましょう。
[参考：Nuxt.jsにおけるenvファイルの利用(初学者向けハンズオン) by@yfujii1127](https://qiita.com/yfujii1127/items/c77bff6f0177b4ff219e)

```terminal
$ npm i @nuxtjs/dotenv
```

nuxt.config.jsの`modules`に`@nuxtjs/dotenv`の設定を追加。

```javascript:nuxt.config.js
module.exports = {
  /*・・・*/
  modules: [
    '@nuxtjs/axios',
    '@nuxtjs/dotenv', /* 追記 */
  ],
  /*・・・*/
}

```

rootディレクトリに`.env`ファイルを作成して、Firebase公式ページからコピーしてきたFirebaseの接続情報を記述します。

```terminal
$ touch .env
```
```:.env
FB_API_KEY='*****************************';
FB_AUTH_DOMAIN='*****************************';
FB_DATABASE_URL='*****************************';
FB_PROJECTID='*****************************';
FB_STORAGE_BUCKET='*****************************';
FB_MESSAGING_SENDER_ID='*****************************';
```
後はNuxtアプリ内でも`process.env.FB_API_KEY`で設定した値を呼び出せるはず・・・

###firebase.initializeApp({***})のプラグイン化

```javascript:/plugins/firebase.js
import firebase from "firebase";
import 'firebase/firestore';

const config = {
  apiKey: process.env.FB_API_KEY,
  authDomain: process.env.FB_AUTH_DOMAIN,
  databaseURL: process.env.FB_DATABASE_URL,
  projectId: process.env.FB_PROJECTID,
  storageBucket: process.env.FB_STORAGE_BUCKET,
  messagingSenderId: process.env.FB_MESSAGING_SENDER_ID
}
if (!firebase.apps.length) firebase.initializeApp(config)

const db = firebase.firestore()
// 起動してみると「timestampsInSnapshotsはもう設定しなくて良いよ！」というエラーが出力されたので、
// 引数なしでfirestore.settings({})をそのまま実行
firestore.settings({})
export { db }
```

```javascript:nuxt.config.js
module.exports = {
  /*・・・*/
  plugins: [
    '~/plugins/firebase.js',
  ],
  /*・・・*/
}

```

これ以降このプロジェクトでFirebase関係のAPIを用いる時は

```javascript
import db from '~/plugins/firebase'
```
とすると、キー情報が入ったFirebase（Cloud Firestore）が使えるようになります。
[参考：FirebaseとNuxt.jsを使ってユーザ認証関係を簡単に作ってみる+1ヶ月前の自分に教えたいリンク集 by@redshoga](https://qiita.com/redshoga/items/da5c0e247e0df314a257)


###仮でデプロイ

`firebase deploy`で初期設定したディレクトリをFirebaseにデプロイできます。

```terminal
$ npm run generate  ## dist/に静的ファイルを吐く
$ firebase deploy   ## dist/をアップ

・・・
Hosting URL: https://***********.firebaseapp.com
・・・
```

仮ですが`https://***********.firebaseapp.com`としてデプロイされました。

すごい簡単！
<br>
<br>
###試しにFirestoreからデータを保存・取得してみる

**🔥ここで躓きました！🔥**


[参考記事](https://qiita.com/ryo2132/items/2881d8223eb2ad3050a1)を基にとりあえず、Firestoreからデータの読み込みと書き込みを試したところで
動作せず、、、以下を試してみましたが解決しませんでした。

コードは以下の通りですが、`.add`における`.then`も`.catch`も動作せず。。。

```javascript
addComment() {
      const now = new Date()
      // コメントをdbへ登録
      db.collection('comments')
        .add({
           content: this.inputComment,
           avatar:
             'https://picsum.photos/50?image=' +
             (Math.floor(Math.random() * 400) + 1),
           createdAt: now
        })
        .then(doc => {
          console.log(`登録に成功しました (${doc.id})`)
        })
        .catch(error => {
          console.log(`登録に失敗しました (${error})`)
        })
      // ダイアログを閉じる
      this.hideCreateForm()
    },

```

#### 確認したこと：コンポーネント外で、`db.collection('comments').add(~)`を実行してみる
同じ挙動で、読み込みや書き込みも動かずエラー出力などもなし。

#### 確認したこと：Firestore rulesに誤りないか
もともとデフォルト設定である「全て許可」でしたが、
さらに追加で`: if true;`を追記してみましたが影響なし。

#### 確認したこと：ドキュメントIDを明示的に指定してみる

```javascript

db.collection('comments').orderBy('createdAt', 'desc')

//自動ID割り当てなので不要なはずの .doc() を使ってみる
db.collection('comments').doc('uBqkISFQ0F191cgGOsy1').orderBy('createdAt', 'desc')
```
変化なし。


##まとめ

１つクリアできれば視界が開けそうなのでリベンジします🍔