病みつきエンジニアブログ

機械学習、Python、Scala、JavaScript、などなど

結婚パーティーのため Nuxt と Firebase でサーバーレスなご祝儀を納品した話

この記事はNuxt.js Advent Calendar 2018の10日目です。

友人の結婚式の二次会向けのコンテンツとして、 「ニコ生」風に投稿された写真やコメントが流れるシステム を作りました。

f:id:yamitzky:20181210203035g:plain

動画だとわかりづらいかもなのですが、広いパーティー会場で、リアルタイムにプロジェクターで写しているような感じです。

f:id:yamitzky:20181210205539p:plain

ユーザーが写真投稿するページや、プロジェクターで写すためのニコ生風ページに Nuxt.js を使っていて、Firebase Hosting 上で SPA としてホスティングしています。デザインは @aixcheck が作ってくれました*1

f:id:yamitzky:20181210214143p:plain

つまり、Nuxt と Firebase で作っている、完全にサーバーレスなご祝儀です*2。ちなみにご祝儀ドメインも取得しました。

こちらのシステムのソースコードは、一部を除いてオープンソースにしています。pages や components は公開していないので、プロジェクトとしては動かないのですが、Firebase や Nuxt での TypeScript の参考になれば幸いです*3

github.com

システム概要

Nuxt.js と Firebase (Hosting, Cloud Firestore, Cloud Functions, Cloud Storage) を使っています。

f:id:yamitzky:20181210212944p:plain

ブラウザから、Firebase SDK を介して Cloud Firestore や Cloud Storage へ直接書き込むようにしています。写真に関しては、Cloud Storage 上に写真が保存されると Cloud Function が立ち上がるようになっており、その中でImageMagick を使って写真を小さく加工した上で Firestore を更新しています(参考)。

写真を加工して小さくしている理由は2つあり、1つは iPhone で撮影すると90度回転してしまう問題の対処、もう1つは特設ページをスマホで見たときに、ギガが減らないようにするためです。

FIrebase の選定はかなり早いうちに決定しました。

  • リアルタイム性
  • なるべく固定費用がかからないようにしたい
  • 0人〜100人規模でなるべく速くスケールする

などが理由です。AppSync も検討したのですが、DynamoDB が「結婚式以外の日に、データベースの固定費用がかからない」という要件を満たせなかっために外しました。Firebase に障害が起きていたら動かなかったので、なかなかリスキーな選択だったと思います。。。

Nuxt の方

Nuxt.js でページを作るにあたって、初めて TypeScript を導入してみましたが、いくつか大変なところがありました。

  • Nuxt.js で TypeScript なサンプルが少ない
  • Vue と Vuex の間での型の連携の弱さ
  • Vue にデフォルトで備わってないフィールドを TypeScript が解決させるのが面倒

Nuxt は SPA モードでデプロイしました。一応サーバーサイドレンダリングが動くような形で作ってはいるのですが、Cloud Functions でコールドスタートが起きたら嫌だなーと思って、検証する時間もなかったので避けた次第です(なので未検証です)。

SSR 対応すると、SSR 未対応なコンポーネントを import するとエラーが起きることがあるので、開発からデプロイまで SPA モードでやると割り切ってもよかったと思います(参考1参考2)。

UI は、Buefy を使いました。プロジェクトがシンプルで複雑なコンポーネントが不要であること、なるべく軽量なページにしたかったのが選定理由です。

プロジェクトのタイムライン

  • 10/14:新郎から「こういうのやりたいんだよねー」と共有を受ける
  • 10/21:Firebase のプロジェクトを作り、技術検証を始める
  • 11/3:ご祝儀ドメインを取得
  • 11/5:会場リハーサル
  • 11/10:完成
  • 11/11:本番

11/10 に締切がやばいことに気づいた図

f:id:yamitzky:20181210222533p:plain

そして当日...

当日は 100 人以上?の参加者がいたそうですが、障害もなく無事に動き、サーバーレス納品ができました。生きた心地がしなかったです。

ただ、端末依存のエラーは起きていてもおかしくないので、そのあたりは Sentry とか使ってトラッキングすればよかったなーと思っています。

また、イベントに関係ない写真の対策として、Firebase Authentication を使って投稿削除権限をつけたり、ML Kit で写真の解析をしたり、、、とかもできたら良かったなーと思います。

Firebase、本当に便利ですね。

かかった費用

f:id:yamitzky:20181210225051p:plain

約7円!!!!!!!!!!!!

まとめ&今後の展望

このシステムは他のイベントにも簡単に転用できるように作っているので、リアルタイムコミュニケーションでイベントにグルーヴ感をもたらしたい方は Twitter などでお声がけいただければと思います*4

また、デザイナーの @aixcheck や、新郎新婦を初めとする多くの方々にご協力をいただきました、ありがとうございます!

*1:一部加工済み

*2:なお、結婚式に参列するにあたってリアルマネーのご祝儀も渡しています。笑

*3:リアルタイムなフォトシェアサービスのような形で、サンプルプロジェクトを作るかもしれません

*4:協力いただいた方々にビールをおごれる程度にはしたいです