こんにちは、株式会社Pentagonでアプリ開発をしている髙谷です。
FlutterでFirebaseを使ったグループチャットの実装を行いましたので、そのポイントをご紹介していきます。
【こんな人に読んで欲しい】
・Firebaseを使ってグループチャットを実装したいエンジニア
【この記事を読むメリット】
Firebaseのデータ構造やフロントの処理フローをおさえることで、グループチャット実装のイメージがわきます。
【結論】
グループチャットの要件をきちんと整理し、一つ一つデータ構造や処理フローに落とし込んでいくことがポイントです。
要件があいまいなままだと、例えばデータ構造を実装途中で変える必要が出てきますし、多くの場合でフロントの大幅な修正にもつながります。
私も痛い目に合いましたが、手戻りがさまざまな箇所に波及していくイメージですね...要件・設計が踏ん張りどころです。
グループチャットの要件とは?16項目を紹介
まずはじめに、グループチャットの要件を整理していきましょう。
今回は前提として、LINEのようなイメージで、チャットルーム一覧画面 => チャットタイムライン画面の2画面を想定しています。
本当にたくさんあるのですが、例えば、以下のような観点を整理していくといいでしょう。
- チャットルームの名前の決め方はどうするか、制約はあるか(デフォルトではメンバーの名前結合など)
- チャットルームの名前は変更できるか、制約はあるか
- チャットルームのアイコンの決め方はどうするか、制約はあるか(デフォルトではルーム作成者のアイコンなど)
- チャットルームのアイコンは変更できるか、制約はあるか
- どんな形式のメッセージが受送信できるか(テキスト、画像など)、制約はあるか(文字数、ファイル容量など)
- チャット内でのユーザー情報は何を表示するか(アイコン、ニックネームなど)、制約のあるユーザー(退会済みなど)はどうするか
- メッセージの受送信時刻はどう表示するか
- 未読・既読数は表示するか
- リアクション機能(いいね、など)はつけるか
- チャットルームのメンバー上限は何人か
- チャットルームへの参加フローはどうするか(招待=>承諾など)
- 途中参加のメンバーは過去のメッセージを閲覧できるか
- チャットルームから退出できるか、制約はあるか
- チャット内でのイベントに応じて通知を送るか、いつ誰に送るか
- その通知はミュートできるか
- チャットルーム一覧で表示するチャット情報は何か(ルーム名、ルームアイコン、最新メッセージ、未読バッジなど)
Firebaseを選んだ理由
チャットでは多くの場合、リアルタイムでフロントとサーバの状態を同期させる必要があります。
送ったチャットが相手にすぐに届かない、などといったことがあってはチャットを使う意義が薄れますよね。
そこで、サーバの状態を監視し、リアルタイムな同期を簡単に実現できるFirebaseを活用して実装することにしました。(Firestore SDKにあるリアルタイムリスナー機能)
Flutter×Firestore間のリアルタイム通信処理については多くの情報が出ているため、今回のブログでは説明を割愛します。
Firestore SDKを使うことで、開発者があまり意識することなく以下のようなメリットを受けられるのがポイントです。
- サーバでデータの変更があった場合のみ読み込みを行うため、読み込みコストを削減できる
- ネットワーク切断などのエラーを検知するとともに自動で復旧し再度監視できる
Firebaseのデータ構造
抽象化したり一部省略したりしていますが、データ(ドキュメント)構造は大まかには以下のようなイメージです。
ドキュメント設計では、データのパスや安全性を担保するため、以下のような点に注意するといいでしょう。
- ドキュメント内に公開情報・非公開情報を一緒に持たせない
- ドキュメント間のリレーションにはリファレンス型を活用する
- ドキュメント間の1対多のリレーションはサブコレクションを利用する
フロントの処理フロー
要件によって変わりますが、グループチャットで必要なフロント処理の例をまとめてみました。
Dartで実装した例をもとに抽象化しているため、特定の言語やフレームワークによらずご参考いただけるかと思います。
プッシュ通知や高速なデータの整合性担保などが必要な場合はサーバサイドの処理が必要ですが、本題から逸れてしまうため今回は割愛します。
- ルーム一覧取得
- ルームコレクションを取得
- 未読管理コレクションの取得(未読バッジ処理)
- ルーム作成
- ルームドキュメントを作成
- ルームドキュメントの参加メンバーへ通知
- メッセージ一覧取得
- メッセージコレクションを取得
- 未読管理ドキュメントを削除(既読処理)
- メッセージ投稿
- メッセージドキュメントを作成
- ルームドキュメントの最新メッセージを更新
- ルームドキュメントの参加メンバーへ通知
- ルームへのメンバー招待
- ルームドキュメントの招待ユーザーリストを更新
- メッセージドキュメントを作成(システムメッセージ処理)
- ルームへの招待の承諾
- ルームドキュメントの招待ユーザーリストを更新
- ルームドキュメントの参加ユーザーリストを更新
- メッセージドキュメントを作成(システムメッセージ処理)
- ルームへの招待の拒否
- ルームドキュメントの招待ユーザーリストを更新
- ルームからの通知のミュート
- ルームドキュメントのミュートユーザーリストを更新
- ルームからの退出
- ルームドキュメントの参加ユーザーリストを更新
- メッセージドキュメントを作成(システムメッセージ処理)
おわりに
グループチャット実装に向けて少しでもイメージをつかんでいただけましたか?
グループチャットはさまざまなアプリに実装されているので、ぜひグループチャットの実装にチャレンジしてみてください。