Nuxt3、Vue3、Firebase V9をDocker上で環境構築

### 前提
- firebaseアカウント作成済
- Dockerインストール済

### 初期フォルダ作成
任意のプロジェクトファイル直下に下記の構造のフォルダを作成します。

```
.
├── Dockerfile
├── docker-compose.yml
└── src/
```

Dockerfileの中身は以下のようにします。

```
FROM node:14.16.1

EXPOSE 3000
```

docker-compose.ymlの中身は下記のようにします。

```
version: '3'
services:
  node:
    build: .
    volumes:
      - ./src:/app
    tty: true
    environment:
      - CHOKIDAR_USEPOLLING=true
    ports:
      - '3000:3000'
      - '24678:24678'
```

### ターミナルでdocker コンテナを立ち上げる

1.ターミナルでアプリ直下に移動し、docker コンテナを立ち上げます。

```
//アプリ直下に移動します。
cd <アプリ直下>

//コンテナをビルドします。
docker-compose build

//コンテナを立ち上げます。
docker-compose up -d

//コンテナのIDを確認します。
docker ps

//コンテナ内に入ります。
docker exec -it <コンテナID> bash

//app直下に移動します。（コンテナ内)
cd app

//nuxt3をインストールします。（コンテナ内)
npx nuxi init <プロジェクト名>

//プロジェクトに移動します。（コンテナ内)
cd <プロジェクト>

//node module をインストールします。（コンテナ内)
npm install

//ローカルサーバを立ち上げて確認する（コンテナ内)
npm run dev

http://localhost:3000/  にアクセスして下記のページが表示されていたら成功

※docker-compose.yml の下記の記述により
ホストのローカルホストポート3000からコンテナ内のサーバー3000ポートにアクセスしています。

ports:
      - '3000:3000'
```
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/69eb3290-645d-3b8e-c51f-8aa157635728.png)

#設定ファイルの修正
nuxt.confit.tsファイルを修正してstrict modeに します。

```javascript
import { defineNuxtConfig } from 'nuxt3'

export default defineNuxtConfig({
  typescript: {
    strict: true
  }
})
```
# Volarのインストール

Vue3 からは VSCode の拡張機能として Vuter の代わりに Volar を使うことが推奨されています。
VsCodeからVolarをインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/37f4c687-7382-1e17-de3c-6c88765023d7.png)

Vuterは干渉を防ぐために無効にしておきます。

# ルーティング 確認のため新規でvueページを作成します。
ルート直下に
pages/index.vue   を作成します。

```vue
<template>
  <div>{{ title }}</div>
</template>

<script lang="ts">
export default {
  setup() {
    const title = "タイトル";
    return { title };
  }
}
</script>
```

app.vueを下記に修正します。

```vue
<template>
  <div>
    <NuxtPage />
  </div>
</template>
```

http://localhost:3000/ に再度アクセスします。
404になる場合は、 一度サーバーを落として 立ち上げなおします。
下記のように表示された場合、正しくルーティングされています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/873bb172-b25c-c269-10d1-61d339be44cd.png)

VsCode上で下記のエラーが表示される場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/2f991458-bf58-a1ef-3e8b-36bc3b262ad8.png)
2021/12/25 の時点でVolar 3.0から0.29.8にダウングレードしたら改善しました。

#Firebaseプロジェクを作成します。

1.Firebaseコンソールからプロジェクトを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/4aa7d6e3-2391-dd5a-502d-5300cd8e4143.png)

2.プロジェクト作成後にFirestore のデータベースを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/03b7e43e-e250-7c5c-bd1c-67d4d8749110.png)
 本番環境モード > 次へ
ロケーションを「asia-northeast1」に設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/86473086-d2e5-2ea6-19f4-27eae28fdeda.png)

3.下記のようにテストデータを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/eaf62ea2-56e2-ca57-e923-da840864c960.png)

4.テストのため一時的にセキュリティールールを変更します。
 サイドメニューから「Firestore Database」を選択。下記画像のように「ルール」をクリックして
下記の「false」を一時的に「true」に変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/5a6be2bb-dcbd-e623-dd21-0386e8cc1a4a.png)

#アプリにFirebase をインストールします。
1.firebaseとfirebase-toolsをインストールします。( コンテナ内)

```
npm install firebase
npm install firebase-tools
```

2.Firebase にログインします。

```
firebase login --no-localhost

※--no-localhost オプションをつけることによりDocker コンテナ内からでもログインできます。
```
3.ターミナルに表示されるURLにアクセスします。
4.ブラウザでログイン後表示されるコードをターミナルの下記に貼り付けます。

```
Paste authorization code here:<ここに貼り付ける>
```
5.firebase init を行います。

```
//firebase　init を行う。
firebase init

// Firestoreを選択します。
◉ Firestore: Configure security rules and indexes files for Firestore

//すでに存在するプロジェクトを使用するを選択します。
Use an existing project
※先ほど作成したプロジェクトを選択します。

//必要に応じて質問に答えます。（エンターで（）内のデフォルトのファイルが作成されます。)
What file should be used for Firestore Rules? (firestore.rules)
What file should be used for Firestore indexes? (firestore.indexes.json)

//下記のように表示されたら成功です。
i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...
✔  Firebase initialization complete!
```
#Firebaseのプロジェクトにアプリを登録します。

1.歯車アイコンをクリックして「プロジェクトの設定」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/ff2d65f6-1110-f767-4075-18751a7ffee2.png)
2. アプリのアイコンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/92e6d69e-d1a1-b435-f389-c627a7a107d8.png)
3. アプリの名前を決めて登録します。
一旦はすべてエンターを押して登録を完了します。

4.作成したアプリが表示されているので、「構成」にチェックを入れて表示されるコードをコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/be6558dd-02e3-d10e-be8f-4bf8ddcd9371.png)

#config.ts を作成します。
1.src/<アプリ名>/firebase/config.tsファイルを作成します。
**** の部分は先ほどコピーした内容を貼り付けます。

```javascript
import { FirebaseOptions, getApps, getApp, initializeApp, FirebaseApp } from "firebase/app";

const firebaseConfig: FirebaseOptions = {
  apiKey: "****************************",
  authDomain: "****************************.com",
  projectId: "****************************",
  storageBucket: "****************************.com",
  messagingSenderId: "****************************",
  appId: "****************************",
  measurementId: "****************************"
};

const firebaseApp: FirebaseApp = !getApps().length ? initializeApp(firebaseConfig) : getApp();
export { firebaseApp };
```

###firebaseとの連携を確認します。
1.firebaseと正しく連携が取れているか確認を行う。

index.vue を下記に書き換える。

```vue
<template>
  <div>{{ nameRef }}</div>
</template>

<script lang="ts">
import { firebaseApp } from '../firebase/config';
import { getFirestore, getDocs, collection } from 'firebase/firestore';
import { ref } from 'vue'
const db = getFirestore(firebaseApp);

export default {
  async setup() {
    let nameRef = ref("")
    const querySnapshot = await getDocs(collection(db, "test"));
    const testList = []
    querySnapshot.forEach((doc) => {
      testList.push(doc.data().name);
    });
    nameRef.value = testList[0];
    return { nameRef };
  }
}

</script>
```
2.http://localhost:3000/ をリロードして、画面上にhogeと表示されていたら連携成功。

以上です。