mogmetfirebaseを使って匿名型チャットmimichaを作ったのでどんな感じに作ったかを紹介TweetPocketこんにちは。大体iOSとかインフラ周り開発担当のもぐめっとです。匿名シェアチャットアプリ」をリリースしました。そこで、構成やプッシュ通知の送り方とか、どんな感じで作っているのかの概要を説明していこうと思います。21日目は@flatfisherさんの、Codelabで学ぶFirebaseとその先でした。アプリ概要アプリの紹介をすると、mimichaはチャットする部屋を作成し、その部屋に参加することで匿名でチャットしあえるサービスです。一度でも参加したことがある部屋に対しては参加一覧に表示されるようになれ、通知などが飛んでくるようになります。構成では、そんなチャットを構成するサーバ側はどんな構成になっているのかを説明していきます。全体構成サービスの構成を図にするとこんな感じになってます。実質ほぼfirebaseですね!今流行りのサーバレスアーキテクチャ的なやつです。インフラの構築と面倒をみなくていいのでとても楽です。Applicationで作っております。ユーザが参加している部屋一覧。各部屋の通知ON・OFFなどもここで管理。Functionsとも深く密接しており、精一杯考えた結果こんな形になりました。functionsにて実装しているのですが、どういうタイミングで使ってるかをご紹介します。ユーザが部屋に参加した時ユーザが部屋に参加したタイミングで、参加一覧に表示できるようにする必要があります。relationRoomsにroomのコピーを作成します。このドキュメントが作成されたタイミングで、CloudFunctionsはこのユーザに対して通知が行えるように、usersとroomsとdeviceTokensに対してユーザの情報を追加しています。chatsサブコレクションに、ドキュメントが作られます。ドキュメント作成タイミングで、CloudFunctionsは部屋に参加していて通知を許可しているユーザ全員に対して、ユーザが保持している部屋情報の更新と、端末に対して通知を行います。このへんが結構一番苦労した点なのですが、流れにするとこんな感じ。通知の設定をみながら上記端末一覧からpush通知を送るこんなかんじでpush通知は送られてます。4あたりが小技を使って頑張ってとったりしているので後ほど小技を紹介しますユーザが部屋を削除した時サブコレクションを入れ子にしている場合、親のドキュメントが削除されても子供のサブコレクションにあるドキュメントは残ったままになっています。ドキュメントを削除しても、そのサブコレクションは削除されません。サブコレクションが関連付けられているドキュメントを削除しても、そのサブコレクションは削除されません。その後もサブコレクションには、リファレンスによるアクセスが可能です。よって参照されるドキュメントは存在する場合があります。ドキュメントを削除するときにサブコレクション内のドキュメントも削除する場合は、コレクションを削除するで説明されているように、手動で削除する必要があります。いうことで、上記警告にあるとおり、ユーザが部屋を削除したタイミングで、その子供にあたるchatsサブコレクションも削除しないといけません。削除の際には、こんな注意事項があります。コレクションを削除するコレクション全体を削除する必要がある場合は、信頼できるサーバー環境からのみ実行してください。クライアントからコレクションを削除することも可能ですが、そのようにするとセキュリティとパフォーマンスに悪影響を与えます。お達しがあったので、CloudFunctionsを使って、roomsドキュメントの削除タイミングでchatsサブコレクションを削除するようにしています。通報の時iOSでコミュニケーションアプリを作る場合、通報をつける必要性があります。mimichaでは、チャット、ユーザ、部屋に対して通報を行うことができますが、通報を行ったらクライアントからはreportsサブコレクションにドキュメントを追加しています。repotsドキュメントが追加されたタイミングで、追加された中身をみて、chatsドキュメント、usersドキュメント、roomsドキュメント、それぞれに通報のフラグを増やして制限をかけるようにしています。reportsサブコレクションにまとめることによって通報の一覧をまとめることができるので、管理の柔軟さをあげております。firestoreの小技とか次に、firestoreを使う上での小技や工夫した点を紹介します。relationRoomsサブコレクションにドキュメントが追加されますが、「すまん」という部屋に参加しているユーザ一覧をusersサブコレクションから取得するといった検索になります。やり方としては、usersドキュメントに、配列データとして、relationRoomsドキュメントのdocumentIdを保管しておきます。使って検索しています。使い方とかは他記事に丸投げ。配列の検索・追加・削除がサポートされたので試してみたチャットの未読機能よくみるチャットの未読機能。普通に数字のカウントアップでやると、「現状のデータを読み込んで」、「+1した値を更新する」といった事になり、チャットの書き込みごとに2回のfirestoreアクセスが生じてしまいます。いうことで、この機能に関してはまたしても出番の配列データを使っています。チャットが作成されたタイミングで、未読管理用のとこにチャットのdocumentIdを挿入しています。クライアント側で、チャットを読んだら、この配列のデータを空にすることで既読したということにしています。hostingについて冒頭でちょろっと触れましたが、web版mimichaはNuxt.jsで作っております。hostingにおくだけで実現しています。ローカルで開発してhostingにデプロイするだけで簡単にアップデートができちゃいます。アプリでユニバーサルリンクを実現するために、jsonファイルもこのhostingにおいてるのですが、その際に、firebase.jsonのheadersにこんな感じでheaderの設定をする必要がありました。"application/json"}]},...firebase.jsonを使えばいい感じにヘッダーの操作やリダイレクトなどもできるので、いい感じに静的サイトを動的な感じで構築できますね。その他サービスfirebase以外にもお世話になっているサービスもご紹介しますimgurfirebase以外のサービスとしては画像管理について、imgurというサービスを使ってます。5chも御用達しとか。storageは使わないような形になりました。Cloudflareタダで使えるCDNの代名詞、Cloudflare。mimichaでは、webは全部Cloudflareを通してアクセスさせております。おかげでキャッシュに乗るのであまりhostingへのアクセスはいかない特典付き。Applicationでwebは作ったのですが、OGP対応はしてないので全部同じ画像とタイトルで表示されちゃうのが悔やまれるポイントです。functionsを使うことでogp対応もできるようなので、いずれできたら対応したいなと思っています。使って全文検索的なこともしてみたいですね!@mogmetの所感firebaseを使うことで、まったくサーバなどを構築しないでサービスを作れちゃいました。実質firebaseは神サービスといっても過言ではないかとおもいます!今後もfirebaseを使っていろいろサービスをリリース予定なので楽しみにしていただければとおもいます!なお、iosとandroidについてのお話に関しては下記をご参考ください。匿名型チャットmimichaを作った際に使ったAndroidライブラリ14選ご静読ありがとうございました。コメントをキャンセルメールアドレスが公開されることはありません。