実質６人日でクイズサイトQuizHubをFirebaseで作ってみた

## 経緯
 空いている時間で、なにか今後とも自分たちも使えそうな内容で、ガガッと何かを作ってみようと言う話をエンジニア仲間うちでしていて、そこで掲題のクイズサイトを作りました。その内容と所感を記載します。

## 目的、目標
 - 開発合宿１回でなんとなく動くレベルまで作る
 - 普段触っていない技術を触ってみる

## できたもの
 http://quizhub.info/

 - クイズを作成して投稿できる。現在は数学/算数のクイズ用途をフォーカス。
 - 数学クラスタの人たちがTwitterで自作問題を投稿してときあってたりしているので、もっと作問/コミュニケーションしやすい場があればいいんじゃないか、ということから作成。
 - 問題作成するときにKaTeX形式で書けるのが頑張ったところ(UI改善はもっと必要ですが)
 - Twitterで人気のあるクイズ作成者に依頼して、問題を掲載させてもらいました。


## かけた工数
 目標は1回の開発合宿で完成でしたが、動くレベルには至らず, 再度開発合宿することに。

 - 開発合宿 x2
  - １回目: 2人で実施 => 2MD
  - ２回目：3人で実施 => 3MD
  
 その他仕様調整、デザイナーの作業 => 1MD

の合計６人日です。(ここでの1人日は徹夜で作業しても当然1日とカウントされています)

## 環境構成

![Screenshot from 2020-04-13 19-03-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18345/898528ff-4df6-02fa-d940-9731e0ffb702.png)

 - Nuxt.js と Firebase only. 以上。(リポジトリなどは除く)

## Firebaseで使用したサービス


 今回はフルfirebaseで完結させる方向性で、以下を使用しました。

 - Firebase Auth
 - FireStore
 - Firebase Hosting
 - Firebase Storage

いつもはAuth0を使うことが多かったのですが、今回は新しいものを学ぶのとFirebaseで完結させるために、FirebaseAuthを選択しました。Cloud Functionは今後使う可能性はありますが、開発時点では使う要件がなかったので、出番はありませんでした。

ここでは、各サービスの所感と似たようなサービスとの比較を少し書いておこうと思います。

## Firebase所感

### Firebase Auth
 Auth0との比較になってしまいますが、これぐらいのさくっと作るレベルでは、どちらも同じぐらい楽に認証が作れたと思います。後述のFireStoreやFirebase Storageのセキュリティルールを設定する際に、Auth0だとカスタム認証の設定の手間がかかるので、Firebaseに閉じる要件であれば、Firebase Authに軍配が上がりあそうです。

### FireStore
 これが今回一番調査/学習に時間を使いました。もともと私含めてメンバーがRDB脳に汚染されていたので、これぐらいの簡単なレベルでも、どうやって設計すべきかということに時間を費やしました。

時間を要したこと、辛かったことは、以下のような内容が挙げられます。

- FireStoreについて調べていたと思ったら, 全身のRealTimeDataBaseについての記事やリファレンスがよく引っかかり混同した。
- RDB脳に汚染されていたため、このレベルの簡単なサイトは設計でも、どうすべきか議論に時間がかかった。特にリファレンスの部分は非正規化して持つべきかどうかなど、なかなか参考になる情報が見つからなかった。FireStoreの入門動画などは、非正規化するもんだよ！と説明はあるが、非正規化を行うための判断基準をどうしたらいいのかということに迷った。
- セキュリティルールの設定がなかなかうまく行かず、PermissionErrorになりうまくデータが更新できないなどのトラブルシュートに時間を要した。

また今回、FireStoreに関して一番参考になったのは以下の書籍でした。ちょうど我々が知りたいと思っている入門的な内容が網羅されており、非常に参考になりました。
(この本に出会ったのが合宿２回目なので、もっと先に知っておけば早く実装できたかもしれません)

**実践Firestore (技術の泉シリーズ（NextPublishing）)**
<a href="https://www.amazon.co.jp/%E5%AE%9F%E8%B7%B5Firestore-%E6%8A%80%E8%A1%93%E3%81%AE%E6%B3%89%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%EF%BC%88NextPublishing%EF%BC%89-%E7%A6%8F%E7%94%B0-%E9%9B%84%E8%B2%B4/dp/484437852X/ref=as_li_ss_il?ie=UTF8&linkCode=li2&tag=rso-22&linkId=040b06f4cc883021ed37db0cfee9afe8&language=ja_JP" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=484437852X&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=rso-22&language=ja_JP" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=rso-22&language=ja_JP&l=li2&o=9&a=484437852X" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />

また、他のサービスと比較すると、FireStoreはオフライン対応やリアルタイム同期を標準でサポートしてくれるので、他のWebアプリではServiceWorker(WorkBox)やWebSocketでやらなければいけないところをすんなりやってくれるので、お手軽だと思います。

### Firebase Hosting
こちらも普段はNetlifyを使用することが多かったのですが、Firebase縛りのためにこちらを選択しました。
Netlifyだとリポジトリを連携すればdeploy-preview(いわゆるfeature環境的な位置づけ)やmasterにデプロイしたら本番にほぼ自動でデプロイしてくれるのですが、Firebase Hostingではそこまでのお手軽さはやってくれなくて、dev環境とproduction環境へのデプロイは、Github Actions で自動化しました。
まあ簡単にできるといえばできるのですが、このレベルでのお手軽さではNetlifyのほうが良さそうです。

### Firebase Storage
今回は画像を保存するだけなので複雑なことはせず少ししか使用していませんでしたが、セキュリティルールがFireStoreと同じように記述できるのは楽だと感じました。


## 全体通してやってみた所感
Firebaseはこれ一本で簡単なWebアプリケーションが作れてしまうので、とてもお手軽と感じ一方で、
Firebaseならではのお作法にある程度親しむ必要があるので、そこの学習コストは必要かなと感じました。
正直Rails, LaravelなどでRDBの上で作ってしまったほうが初速は早かったと思います。

ただ、Firebaseのお作法に慣れてしまえばかなり開発速度が上がると感じたので、
今後似たような小さなWebアプリケーションを作成する際には、積極的に使用していきたいと思います。