👨‍🎤

Next.js + Firebaseでリアルタイムなクイズアプリ作った話

2021/01/22に公開

リアルタイムにクイズ大会を開けるアプリ「mondai」

今回作ったアプリ「mondai」は、ブラウザだけで簡単に使えるクイズアプリです。クイズアプリといっても、一人で淡々と解いていくというよりも、友達やイベントなど大人数で同時にクイズを解いていける、クイズ大会をオンラインで実現するサービスになっています。

例えば、友達同士で通話してる時、ちょっと手軽なミニゲームしたくなった時や、
イベントでのアイスブレイクに使うと、会話をつなげるツールになります!

https://twitter.com/Yahimotto/status/1352151919725219842?s=20
https://mondai.page/

サービスを作るきっかけ

作業しながら雑談の生配信を見ていた際に、大勢の視聴者が手軽に参加できるミニゲームのようなサービスがないことを気づきました。コロナ禍で「オンライン+娯楽」を提供できるツールが求められていましたし、自分も欲しかったのでその点をベースに考えはじめました。

そして、大勢のユーザーが気軽に参加でき、大人数で遊んだ時でも破綻せず、簡単な操作で楽しんでもらえるコンテンツとは何か考えた時に、クイズを使ったサービスを思い浮かびました。

開発期間

1ヶ月:178 commits

1ヶ月でなんとかリリースできました。

構成

Next.js + TypeScript + Firebase(Cloud Firestore)で構築しました。

TypeScriptを今回のプロジェクトで初めて1から使いましたが、Propsに対するIDEの補助がとてもよかったです!Next.jsもReactも今回の開発でほとんど初めて使いましたが、これまで使っていたNuxt.jsよりも自由度が高く素直に使えて良いなーとなっています。デプロイ先はもちろんVercelです。

処理に最低限必要なAPIの実装には、Next.jsのAPI Routeを使っています。しかし、Vercelに依存しすぎるのは結構リスクが高いので、スケールした場合には、Cloud Functionsにでも引っ越ししたいなと思っています。

Firebaseはよいぞ

個人開発では、インフラの管理にリソースが全く避けないこともあり、Firebaseは最高です!

ただ、ドキュメントのバリデーションやセキュリティを厳格に管理しようとすると、Firestoreのセキュリティルールを厳格に書く必要があるため、複雑になり、結果実質readのみしか使えない状況になってしまいます。

最初からデータ構造を指定してデザインからサービスからモデリングまですればいいだけのお話なのかもしれませんが、難しかったです😣

FirestoreのSnapshot Listenerを活用しよう

Firestoreは、便利なだけではなく、リアルタイムにドキュメントの更新を取得できることは知っていましたか?これを活用することで、今回のリアルタイムクイズ大会を開けるアプリが構築できました。リアルタイムの同期は結構ハードルの高いものと思われがちですが、本当に簡単です!

今回使ったSWR経由でFirestoreにアクセスできる"@nandorojo/swr-firestore"を使うと、プロパティを追加するだけで、React Hooksを通したリアルタイム取得が可能です。

const { data } = useDocument(`users/${user.id}`, { listen: true })

https://github.com/nandorojo/swr-firestore/

ReactでCSSを書く時どうしたらいいのか

ReactベースでCSSを使ったスタイリングを行う際に、何を使えばいいのかいまだによくわかりません。styled-componentはIDEでの表示がわかりにくくなりそうだし、CSS moduleで各コンポーネントに1ファイル設置するとなると管理が大変だし...。ということで、今回はVercelのstyled-jsxを使いました。

styled-jsxでSCSSを書く場合には、下のプラグインが必要です。
https://www.npmjs.com/package/styled-jsx-plugin-sass

デザイン

デザインツールのFigmaでデザインを大体で起こして、CSSでマークアップする際にかっちり決めていく、という感じでUIをつくりました。

個人開発なので、ある程度自由度をもちながらデザインしていくことで、スピードを持ちながらデザインできました!

ユーザーリサーチ

開発の節目節目で、友達や参加しているコミュニティの方々を誘って、3回に分けて、計30人ぐらいの方にに参加してもらいました!

1回目

クイズ問題を作って、クイズ大会を開くなど、基本的な機能を実装した段階つかってもらいました

見つかった問題:

  • 🤔動作に対して、レスポンスがわかりにくく、迷う
  • 🤔使い方を教えて貰わないとわかりにくい

改善したポイント:

  • 😍React toastifyを使って、動作に対してレスポンスを表示するように
  • 😍フォームのラベルなどを通して、読むとだいたいわかるように

2回目

8人ぐらいでクイズ大会をつくってもらってあそんでもらいました

見つかった問題:

  • 🤔ボタンのOn/Offがわかりにくい
  • 🤔クイズ大会開始中にダッシュボードに行くと何も表示されない
  • 😣そもそもクイズを作るのにハードルがある

機能になかったけどみんなしていたこと:

  • 🧐正解状況をスクショして、トークルームに貼っていた

改善したポイント:

  • 😍ボタンの色使いなど、デザインを変更。
  • 😍表示抜けされていたページにヘルプなどを追加
  • 😍「クイズトピック」というクイズを作るお題を提供するページを追加
  • 😍正解状況を簡単に共有できるように

3回目

友達と通話してるときにさらっとつかってみました

見つかった問題:

  • 😊使い方をサポートしたほうが、より使ってくれる

改善したポイント:

  • 😍「初めて」をサポートするチュートリアルモーダルを追加

ユーザーリサーチを繰り返すことで、自分だけでは想定していなかったような機能やわかりにくさを見つけ、改善することができました!

個人開発でも、ある程度友達間で使ってもらうことによって、モチベーション向上にも繋がります!やってよかった!

参考にしたリポジトリ

vercel/commerce

https://github.com/vercel/commerce

VercelがどのようなNext.jsの実装を行っているか、コードスタイルを確認したかったので、よく見ていました。

https://github.com/neet/refined-itsukara-link

Next.js全体のコードスタイルや、localstorageを使ったチュートリアルの実装方法などを参考にさせていただきました!

今後

自分で作った中で一番つかってて楽しいサービスなので、いろんなところで使ってもらえるように進めて行きたいと思います!

現在広告でのマネタイズを準備していますが、使ってみて結構企業やイベント向けでもあるなと感じているので、共同編集を可能にするようなサブスクリプションも良さそうです。

初React(Next.js)だったので、結構コードスタイルが整ってない部分もありますので、リファクタリングもすすめつつ、プロダクトを広めていけるよう、がんばります!


クイズアプリ:mondai」ぜひ使ってください!!クイズも作ってみてもらえると🙏
https://mondai.page/

Twitterのフォローもお願いします!
https://twitter.com/Yahimotto

Discussion