【Firebase】Firebaseのチュートリアルでチャットアプリを作ってみた【ホスティング編】


## Google Codelabs チュートリアル
個人的にAngularでやりたかったので、こちらのチュートリアルを選定しました。
[Cloud Functions for Firebase (Angular)](https://codelabs.developers.google.com/codelabs/firebase-cloud-functions-angular/index.html#0)

![スクリーンショット 2020-01-03 10.36.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/d9e2d24e-dec9-b84a-4c12-01b3955ce594.png "スクリーンショット 2020-01-03 10.36.03.png")


## Git clone
Gitからサンプルプロジェクトを持ってきます。

![スクリーンショット 2020-01-03 10.37.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/e25fffb8-88e1-1c24-7d01-8bed05272a60.png "スクリーンショット 2020-01-03 10.37.32.png")

```sh:console
git clone https://github.com/firebase/friendlychat-web
```

![スクリーンショット 2020-01-03 10.37.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/383d4b2e-6b81-203f-c3f5-f30c8b42e75e.png "スクリーンショット 2020-01-03 10.37.11.png")

ただ、この中で今回使うのは、`cloud-functions-angular-start`だけなので、中身を取り出してほかは消します。

![スクリーンショット 2020-01-03 10.40.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/78c0942e-3cc4-be5c-f2c7-732caa3acb18.png "スクリーンショット 2020-01-03 10.40.08.png")]

ここは自由ですが、僕はここで`git init`でバージョン管理します。
あとで修正する場所とかわからなくなるの嫌なので・・・

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

まずプロジェクトを作っていきます。

![スクリーンショット 2020-01-03 10.45.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/a6e46d30-793d-15c6-ee56-18f5e4117fae.png "スクリーンショット 2020-01-03 10.45.44.png")

プロジェクト名を`FriendlyChat`にして、続行します。


![スクリーンショット 2020-01-03 10.46.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/cdc45413-404b-5177-7bbe-17ac315c8179.png "スクリーンショット 2020-01-03 10.46.24.png")

今回はサンプル作成なのでAnalyticsは使わずに行きます。
これを有効にした場合は、Analyticsを紐付けるGoogleアカウントを聞かれますのでｗ
もちろん、あとから有効にすることも可能です。
このままプロジェクト作成に進みます。

![スクリーンショット 2020-01-03 10.50.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/784cb4e1-0a93-4c52-9918-e34c9decfda5.png "スクリーンショット 2020-01-03 10.50.54.png")

少ししたらプロジェクトが完成します。
続行で次に行きます。

![スクリーンショット 2020-01-03 10.52.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/fbee5f78-99b1-92ad-eb6f-3ee684a7da55.png "スクリーンショット 2020-01-03 10.52.04.png")

ダッシュボードに移動するので、これでベースになるプロジェクトは完成です。

![スクリーンショット 2020-01-03 11.01.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/890a49fa-3d98-76d7-7577-09a8bdb48d4f.png "スクリーンショット 2020-01-03 11.01.03.png")

## WebApplicationの初期化
### Firebaseへアプリの登録

サンプルコードにFirebaseを追加していきます。
まずはダッシュボードにあるWebアプリへの追加ボタンを押します。

![スクリーンショット 2020-01-03 11.17.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/3ac0f191-935a-5d97-dc63-a46af7e4b04c.png "スクリーンショット 2020-01-03 11.17.46.png")

次の画面ではApplicationのニックネームを入力します。
ここでは、`friendlychat-angular`と入力します。
プロジェクト名と一緒にせずに見分けが付くようにしました。

加えて、Hostingの設定も自動で設定させるためのチェックをつけて、アプリ登録に進みます。

![スクリーンショット 2020-01-03 11.35.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/164bf43a-097b-17db-271f-6c60fef684e2.png "スクリーンショット 2020-01-03 11.35.19.png")

### Firebase SDK の追加

次の画面では、`<body>`タグに埋め込むscriptのスニペットが表示されます。

![スクリーンショット 2020-01-03 11.36.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/d033b53a-c0a5-ddf6-f528-a80716b2af49.png "スクリーンショット 2020-01-03 11.36.23.png")

先程Githubからcloneしたプロジェクトのindex.htmlに埋め込みます。
埋め込んだら次に進みます。

```html:index.html
<body>
  <app-root>Loading...</app-root>
  <!-- The core Firebase JS SDK is always required and must be listed first -->
  <script src="/__/firebase/7.6.1/firebase-app.js"></script>

  <!-- TODO: Add SDKs for Firebase products that you want to use
      https://firebase.google.com/docs/web/setup#available-libraries -->

  <!-- Initialize Firebase -->
  <script src="/__/firebase/init.js"></script>
</body>
```

### Firebase CLI のインストール

次は`frebase-tools`をnpmで取得します。
画像では`グローバル領域`にインストールしてますが、**嫌なので** `yarn`でプロジェクト内の、devDependenciesみにします。

![スクリーンショット 2020-01-03 12.12.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/c11f1b33-fc6d-20a8-137e-0ed1e4182ecd.png "スクリーンショット 2020-01-03 12.12.31.png")

プロジェクト内で開発時利用にするので、こちらのコマンドで追加

```sh:console
$ yarn add --dev firebase-tools
```

`package.json`にscriptを追加します。
追加したのは`"fb": "firebase"`です。

```json:package.json
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build --prod",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "fb": "firebase"
  },
```

### Firebase Hosting へのデプロイ

次の画面では、`Firebase CLI`からFirebaseへdeployする作業ですが、実際はログイン作業のみでOKです。

```sh:console
$ yarn fb login
yarn run v1.21.1
$ firebase login
i  Firebase optionally collects CLI usage and error reporting information to help improve our products. Data is collected in accordance with Google's privacy policy (https://policies.google.com/privacy) and is not used to identify you.

? Allow Firebase to collect CLI usage and error reporting information? Yes
i  To change your data collection preference at any time, run `firebase logout` and log in again.

Visit this URL on this device to log in:
https://accounts.google.com/o/oauth2/auth?client_id=**********

Waiting for authentication...

✔  Success! Logged in as *******@gmail.com
✨  Done in 121.47s.
```

コマンド結果は上記のとおりですが、途中ブラウザが立ち上がって以下の画面が表示されます。

まず、自分のGoogleアカウントを選びFirebaseからのアクセスを許可します。
このあたりは他のGoogleAuthenticationとか変わらないです。

![スクリーンショット 2020-01-03 12.22.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/d4fc732d-948b-6612-c124-8a5fde44277f.png "スクリーンショット 2020-01-03 12.22.40.png")

![スクリーンショット 2020-01-03 12.23.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/233ae411-0816-aba3-94c8-b815b67c29bd.png "スクリーンショット 2020-01-03 12.23.43.png")

最後にこの画面がでたら、ターミナル側で`Success`が表示されています。
![スクリーンショット 2020-01-03 12.23.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/96ee4cc8-0b53-f283-7cd2-a11d791d81e1.png "スクリーンショット 2020-01-03 12.23.51.png")


次のコマンドの`firebase init`はなしでOKです。
各Serviceの`.rules`ファイルを作るためのコマンドですが、Githubから取得したプロジェクトには既に`.rules`ファイルがあるため、行うと上書きするか問われます。

新規でプロジェクトを立ち上げる場合のみに行いましょう。


最後にdeployですが、ここも一旦スルーします。
Angularは一度buildをしないといけないのと、`environment`の設定が必要なので。

ログインが終わりましたら、コンソールに戻ります。
画面に戻ると、Applicationが1つ追加されています。

![スクリーンショット 2020-01-03 12.59.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/825e6a18-779c-cca7-fc49-506f8c843b7a.png "スクリーンショット 2020-01-03 12.59.34.png")

![スクリーンショット 2020-01-03 12.57.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/b697fa22-e0c3-9e66-f9a3-1399098e4bd1.png "スクリーンショット 2020-01-03 12.57.58.png")


### Environmentの追記

初期化の最後に環境変数の設定を行います。
Applicationの画面から以下のボタンをで詳細画面を開きます。

チュートリアルには書いてないですが、リージョンの指定をしないとStorageの作成でコケます。
なので、このタイミングでリージョンを指定します。

![スクリーンショット 2020-01-03 16.40.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/fb9434c0-841f-bfbc-bd54-21bd21b7858d.png "スクリーンショット 2020-01-03 16.40.39.png")

`asia-northeast1(東京リージョン)`を指定します。

![スクリーンショット 2020-01-03 16.41.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/9caabd16-6b5b-2f57-5014-00a7138cc160.png "スクリーンショット 2020-01-03 16.41.07.png")


選択したら、完了ボタンを押します。
尚、無料枠を使っている間はリージョン変更はできないみたいです。

![スクリーンショット 2020-01-03 16.41.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/e65a1ba4-8173-edb5-aa0f-1f9c4a18afe5.png "スクリーンショット 2020-01-03 16.41.16.png")

リージョン指定が完了したら以下の様に表示されます。

![スクリーンショット 2020-01-03 16.42.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/9aecb57c-33cb-47f3-ce59-461beaad6bd7.png "スクリーンショット 2020-01-03 16.42.22.png")


### Firebase Cloud MessagingのID追加

環境変数に追加したmessagingSenderIdを`src/firebase-messaging-sw.js`にも追記します。

```js:firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/7.6.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.6.1/firebase-messaging.js');

// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
firebase.initializeApp({
  // TODO add your messagingSenderId
  messagingSenderId: '722748052014'
});
var messaging = firebase.messaging();

```

### Google Authを有効化

開発メニューのAuthenticationを選択し、ログイン方法を選びます。

![スクリーンショット 2020-01-03 23.47.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/79f43b3f-665a-f58d-8bee-80533b609c6f.png "スクリーンショット 2020-01-03 23.47.06.png")

Googleアカウントでのログインを有効にするため、編集のアイコンを押します。

![スクリーンショット 2020-01-03 23.47.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/8176b9ed-c5cc-688b-86cc-af1b8ff14bf8.png "スクリーンショット 2020-01-03 23.47.34.png")

編集画面の右上のトグルボタンで有効にし、プロジェクトのサポートメールを選択します。
おそらくプロジェクトに参加されているメンバーのメールアドレスが表示されます。
今回は個人なので自分のメールアドレスしか選択肢がなかったので、自分のメールアドレスを選択しました。
メールアドレス選択後に完了ボタンを押します。

![スクリーンショット 2020-01-03 23.48.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/a825b207-fb9a-e49c-887d-b91dc04f82bf.png "スクリーンショット 2020-01-03 23.48.04.png")

Authenticationの画面で、Googleのステータスが有効になっていたら完了です。

![スクリーンショット 2020-01-03 23.48.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/0303f6ae-7ac7-e0f3-d4aa-7bc65af70972.png "スクリーンショット 2020-01-03 23.48.36.png")


## Angular CLIのインストール

チュートリアル用のプロジェクトには既にAngularCLIが`package.json`に含まれているため不要です。

![スクリーンショット 2020-01-03 13.26.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/50989a3c-d242-97dd-dd4e-67689e78228c.png "スクリーンショット 2020-01-03 13.26.12.png")

## Firebase CLIのインストール

さっきインストールしたので不要です。

![スクリーンショット 2020-01-03 13.26.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/f5fea6dc-75c6-e713-b959-8c5cd77e4bbd.png "スクリーンショット 2020-01-03 13.26.26.png")

## Firebaseへのdeploy

今回の記事のゴールになる、FirebaseのHosting機能へのデプロイになります。

<img width="1487" alt="スクリーンショット 2020-01-04 0.40.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/ada845a2-c307-ba6d-f635-12fdd2727822.png">

### build
deployですが、Angularは一度buildをしないといけないので先にbuildします。

```sh:console
$ yarn build
yarn run v1.21.1
$ ng build --prod
Date: 2020-01-03T03:43:00.961Z                                                          
Hash: dfb6376133e3c5ab2a35
Time: 73431ms
chunk {0} main.4af57583d537a669e5ff.bundle.js (main) 1.43 MB [initial] [rendered]
chunk {1} polyfills.0b33fa85a7a0d61fff6f.bundle.js (polyfills) 63 kB [initial] [rendered]
chunk {2} styles.b8bba95fab8adefc8f7b.bundle.css (styles) 84 bytes [initial] [rendered]
chunk {3} inline.318b50c57b4eba3d437b.bundle.js (inline) 796 bytes [entry] [rendered]
✨  Done in 77.08s.
```

### プロジェクト指定

CLIでfirebase内のProfectを使うか指定します。

```
$ yarn fb use --add
yarn run v1.21.1
$ firebase use --add
? Which project do you want to add? friendlychat-58148
? What alias do you want to use for this project? (e.g. staging) friendlychat

Created alias friendlychat for friendlychat-58148.
Now using alias friendlychat (friendlychat-58148)
✨  Done in 10.08s.
```

`What alias do you want to use for this project?`はフリー入力で、ここでは`friendlychat`と入力してます。
指定後にはprofectディレクトリ内の`.firebaserc`に以下のような記述がされます。
  
```json:.firebaserc
{
  "projects": {
    "friendlychat": "friendlychat-58148"
  }
}
```

### deploy

`package.json`にscriptを追加します。
追加したのは`"deploy": "firebase deploy --except functions"
`です。

```json:package.json
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build --prod",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "fb": "firebase",
    "deploy": "firebase deploy --except functions"
  },
```

コマンドからdeployします。

```bash:console
$ yarn deploy
yarn run v1.21.1
$ firebase deploy --except functions

=== Deploying to 'friendlychat-58148'...

i  deploying database, storage, hosting
i  database: checking rules syntax...
✔  database: rules syntax for database friendlychat-58148 is valid
i  firebase.storage: checking storage.rules for compilation errors...
✔  firebase.storage: rules file storage.rules compiled successfully
i  storage: uploading rules storage.rules...
i  hosting[friendlychat-58148]: beginning deploy...
i  hosting[friendlychat-58148]: found 12 files in dist
✔  hosting[friendlychat-58148]: file upload complete
i  database: releasing rules...
✔  database: rules for database friendlychat-58148 released successfully
✔  storage: released rules storage.rules to firebase.storage
i  hosting[friendlychat-58148]: finalizing version...
✔  hosting[friendlychat-58148]: version finalized
i  hosting[friendlychat-58148]: releasing new version...
✔  hosting[friendlychat-58148]: release complete

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-58148/overview
Hosting URL: https://friendlychat-58148.firebaseapp.com
✨  Done in 22.53s.
```

## Firebaseへのdeploy後

### ホスティング画面
![スクリーンショット 2020-01-03 23.56.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/6908cf75-4afa-b3d0-2463-dcda2c932a3b.png "スクリーンショット 2020-01-03 23.56.05.png")


## 動作検証
### ページ表示

deploy後に表示されたURLに飛んでみました。

![スクリーンショット 2020-01-03 17.15.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/068b088c-3e9c-7b0d-e7e9-b100e36923c2.png "スクリーンショット 2020-01-03 17.15.15.png")

### ログイン

右上のログインボタンを押すと、GoogleAccountの選択画面がでます。
`Authentication`の設定がされているため、GoogleAccountでのApplicationへのログインが出来るようになってます。

![スクリーンショット 2020-01-04 0.02.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/1d75bc78-c904-07cb-7d76-e35cd536933a.png "スクリーンショット 2020-01-04 0.02.29.png")

GoogleAccountでのログインをすると右上にはアカウント情報の表示と、ログアウトが表示されるようになります。

![スクリーンショット 2020-01-04 0.03.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/9ca5e3c0-b1e0-613a-ab2c-6e57d285a64e.png "スクリーンショット 2020-01-04 0.03.16.png")

`Authentication`の設定画面でも、新規のユーザーが表示されるようになります。

![スクリーンショット 2020-01-04 0.04.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/21fc3a81-d0fa-aefa-f301-0ca9f0086335.png "スクリーンショット 2020-01-04 0.04.36.png")

### メッセージ送信

実際にコメントを入れてSendボタンでメッセージを飛ばします。

![スクリーンショット 2020-01-04 0.13.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/712dcc04-4300-6452-030c-cc2715409448.png "スクリーンショット 2020-01-04 0.13.08.png")

すぐその場で飛ばしたメッセージが表示されます。

![スクリーンショット 2020-01-04 0.13.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/6a6c2215-3922-b1b0-39d1-7027809c8ffc.png "スクリーンショット 2020-01-04 0.13.16.png")

このときに初めてコンソール側でデータベースが作られている事が確認できます。

![スクリーンショット 2020-01-04 0.15.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/35615427-72f7-c161-4e42-28fdd651cf6d.png "スクリーンショット 2020-01-04 0.15.23.png")

ここまでで一応、`function`で追加する機能以外は実装できたことになります。
`Google Codelab`の進捗としては、13ページ中6ページまでが終わったことになります。


## まとめ
Qiitaを書きながらなのもありましたが、意外と時間がかかりました💦
ここまではホスティングまでなので、functionはまた別で書きたいと思います。

詳しいまとめは別途ブログの方に書いてきます。

## 追記 2020/1/4
全体の感想や躓いたところ、未解決部分はブログに書きました。
https://hisa-tech.site/try-firebase-chatapp-hosting/

## 修正 2020/1/4
Firebaseへのホスティングの場合、環境変数は`<body>`タグに組み込んだ`<script src="/__/firebase/init.js"></script>`だけで大丈夫でした！
`init.js`の中身見たら同じこと書いてありました💦

こちらをご参考に
https://firebase.google.com/docs/web/setup?authuser=0#add-sdks-initialize