Firebaseを使ったチャットアプリの導入と機能追加

**Firebase**とは、Googleが提供しているアプリ開発プラットフォームである。
Firebaseがサンプルコードを提供しているチャットアプリを導入する流れについて説明する。
また、導入したアプリに独自で追加した機能についても紹介する。

## 開発環境
この記事の内容を実行した際の開発環境は以下の通り。
* PC
MacBook Air
プロセッサ：1.6 GHz デュアルコアIntel Core i5
メモリ：8GB
OS：macOS Ventra バージョン13.0

* コードエディタ
Visual Studio Code
バージョン： 1.71.1 (Universal)

* ブラウザ
Google Chrome
バージョン： 107.0.5304.87（Official Build）

## 導入方法
Firebase Codelabが公開している[ドキュメント]("https://firebase.google.com/codelabs/firebase-web?hl=ja#0")に沿って作業をしていくことでチャットアプリは導入できる。(閲覧日：2022/11/3)
ここでは、導入する上でつまづいた箇所を補足する。

#### [2. サンプルコードを入手する]("https://firebase.google.com/codelabs/firebase-web?hl=ja#1")
Visual Studio Code（以下、VSCode）で[GitHubリポジトリ]("https://github.com/firebase/codelab-friendlychat-web")をクローンする方法について補足する。

1\. VSCodeでターミナルを開き、クローンしたリポジトリを保存したい先のディレクトリに移動するコマンドを入力する。
```
cd ‘クローンを保存したい先のディレクトリ’
```

2\. リポジトリのURLを取得しする。リポジトリのクローンを行うコマンドを入力する。
```
git clone ‘コピーしたURL’
```
URLのコピーはリポジトリの以下から取得できる。
![スクリーンショット 2022-11-03 12.22.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633665/02a9ca2b-e6aa-1dd3-c9f7-dcea0a3ef136.png)


3\. リポジトリのクローンを保存したディレクトリに移動し、ソースコードを開くコマンドを実行する。
```
cd ‘クローンを保存したディレクトリ’
code .
```
:::note info
補足
`code .`が機能しない場合は以下を参照。
[code.コマンドがcommand not found となる]("https://qiita.com/noto_web/items/eb5d6a904c459b8c6dea")
:::

#### [5. スターター アプリをローカルで実行する]("https://firebase.google.com/codelabs/firebase-web?hl=ja#4")
PCの再起動やVSCodeアップデートした後などは、以下のコマンドが実行中であるか確認が必要。
```
firebase serve --only hosting
```

:::note info
補足
ポート5000が使えない場合は以下を参照。
[【MacOS Monterey12】ポート5000を利用しようとすると「Address already in use」が発生する]("https://qiita.com/NasuPanda/items/ac94c496d42aac4fcb6d")
:::

#### [6. Firebase のインポートと構成]("https://firebase.google.com/codelabs/firebase-web?hl=ja#5")
PCの再起動やVSCodeアップデートした後などは、以下のコマンドが実行中であるか確認が必要。
```
npm run start
```

#### [10. 画像を送る]("https://firebase.google.com/codelabs/firebase-web?hl=ja#9")
この時点では、画像アップロードボタンから画像を送信しても、アプリのUI上に画像は表示されない。
以降のステップ([13. Cloud Storage のセキュリティ ルール]("https://firebase.google.com/codelabs/firebase-web?hl=ja#12"))で画像が表示されるようになるので、引き続き作業を進めていく。

参考までに、同様の質問が[GitHub]("https://github.com/firebase/codelab-friendlychat-web/issues/658")にもある。

## 追加機能の実装
GitHubで公開されているサンプルコードを編集し、以下の機能追加を行った。

#### メッセージ表示数の上限をなくす
サンプルコードでは、[9. メッセージを読む]("https://firebase.google.com/codelabs/firebase-web?hl=ja#8")でチャットの最後の12メッセージのみを表示させてる。[クエリ機能の`limit`]("https://firebase.google.com/docs/firestore/query-data/order-limit-data?hl=ja")を使用してメッセージ表示数を制限しているので、以下の部分をコメントアウト(または削除)するとメッセージ表示数制限がなくなる。

```javascript:index.js
const recentMessagesQuery = query(
    collection(getFirestore(), "messages"),
    orderBy("timestamp", "desc")
    // limit(12) // Comment Out for showing all messages.
  );
```

:::note warn
注意
ソースコードを編集すると`http://localhost:5000`では変更が反映されるが、デプロイ後のページでは反映されていないので、もう一度、[15. Firebase Hosting を使用してアプリをデプロイする]("https://firebase.google.com/codelabs/firebase-web?hl=ja#14")を実行する。
:::

#### 送信日時の表示ができるようにする
まず、`html`内の`MESSAGE_TEMPLATE`に、クラス名`time`の送信日時表示用の新たな`div`要素を追加する。
```html:index.html
// Template for messages.
var MESSAGE_TEMPLATE =
  '<div class="message-container">' +
  '<div class="spacing"><div class="pic"></div></div>' +
  '<div class="message"></div>' +
  '<div class="name"></div>' +
  '<div class="time"></div>' +
  "</div>";
```

次に、関数`displayMessage`の内容を変更し、投稿日時が表示されるようにする。
```javascript:index.js
  div.querySelector(".name").textContent = name;

  // Show the date and time of message.
  const date = timestamp.toDate();
  const dateFormat =
    date.getFullYear() +
    "/" +
    (date.getMonth() + 1) +
    "/" +
    date.getDate() +
    " " +
    date.getHours() +
    ":" +
    ("00" + date.getMinutes()).slice(-2);
  div.querySelector(".time").textContent = dateFormat;

  var messageElement = div.querySelector(".message");
```
`Timestamp`を`Date`型に変換して取得する。取得したデータから年や月など各要素を取得して、先ほど`html`で追加した`div`の`textContent`に代入する。*分*の表記に関しては常に２桁表示になるようにした。

参考ページ
・[`Date`型への変換について]("https://bnsgt.hatenablog.com/entry/2021/10/15/092713")
・[時間要素の取り出しについて]("https://www.delftstack.com/ja/howto/javascript/javascript-convert-timestamp-to-date/")
・[桁数合わせ(ゼロパディング)について]("https://rfs.jp/sb/javascript/js-lab/zeropadding.html")

最後に、cssでスタイルを設定する。
```css:main.css
.message-container .name {
  display: inline-block;
  width: 50%;
  /* 一部省略 */
}

.message-container .time {
  display: inline-block;
  width: 50%;
  text-align: right;
  color: gray;
  font-size: 10px;
  box-sizing: border-box;
}
```
表示方法を`inline-block`として、`nama`クラス(投稿者表示用の要素)と`time`クラスの`width`プロパティをどちらも50%として横並べで表示させている。また`time`クラスは右寄せすることで、投稿日時はトークルーム右端に並んで見えるようになる。

参考ページ
・[`inline-block`について]("https://saruwakakun.com/html-css/basic/display#section4")
・[インライン要素の右寄せについて]("https://www.acky.info/tips/css/00001.html")

:::note info
補足
cssの変更が反映されない場合はキャッシュを消す。
Chromeのデベロッパーツール開く(⌘ + Option + i) 
-> 歯車マーク(右上) 
-> Preferences 
-> Network 
-> Disable cache (while DevTools is open) にチェック 
-> リロード(⌘ + R)
:::

***
最後まで読んでいただきありがとうございました！
***