【Firebase, Nuxt】リアルタイムなスライド共有サービスを作ってハッカソンで優勝した話

昨年末に[Firebaseのアイデアソン/ハッカソン](https://firebase-community.connpass.com/event/149189/)に参加しました。
その場で出会った３名で即席チームを結成して、約1ヶ月でFirebaseを使ったサービスを開発しました。
その結果、<b>最優秀賞</b>を獲得し、更に１ヶ月で機能を追加して、<b>サービスを正式リリース</b>しました!

自分なりに大きな経験になったので、その経緯をサービス紹介を含めて公開します。
個人開発したいと思っているエンジニアで、参考にしてくれる人がいたら幸いです。

## どんなサービスか
"SlideLive（スライドライブ）"といいます。
<b>勉強会やセミナーのライブ感を飛躍的に高めるリアルタイムスライド共有サービス</b>
です。
[![top.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337621/643b7769-7efb-f960-ca83-5c59fbe08b60.png)](https://slidelive.jp/)

## SlideLiveのコンセプト
### 勉強会をライブに

私はプレゼンが苦手です。
「アイスブレイク」ってどうやったらいいのでしょうか？
「勉強会でプレゼンしている時にリアクションが無く緊張する」ことってありませんか？
そんな課題認識からサービスを発想しました。

SlideLiveは、<b>参加者からのリアクションを最大限引き出して、発表者と参加者の距離を近く</b>します。
発表者からの一方通行ではなく、参加者からフィードバックして、双方向で一緒に盛り上がれる、ライブのような「理想の勉強会」を演出します。
また、そのリアクションがアーカイブされて、勉強会の後でも楽しむことができます。

<img width="1174" alt="スクリーンショット 2020-01-11 21.57.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337621/327f00ad-e291-2256-88f8-9332fea5818f.png">

## 勉強会のライブ感を高める機能

### 発表者ページのリアルタイム同期
今時の参加者は、PCやスマホを見ながら参加している人が多いので、手元の画面に発表者のページをライブで同期させています。
発表者のPC画面（左）をページ遷移すると、参加者のスマホ画面（右）が同期して切り替わります。
![slide1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337621/11c19380-9b70-0be4-2b68-58cf0d50f7b0.gif)

### コメント&いいね機能
各ページに思いついたコメントを参加者が書き込こみ、そのコメント（右）がすぐに発表者画面（左）で共有されます。
参加者のコメントに"いいね"がついて、コメント発生が促されます。
発表者がコメントを受けて説明を追加するなど、双方向のコミュニケーションが生まれます。
![comment1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337621/d777fcc7-1606-c7d8-e0da-4711fd7d39e3.gif)

### スライドＱ＆Ａ機能
発表者からアンケートやクイズを出題して、参加者が自分のスマホやPCから回答を入力できます（某クイズ番組方式）。
勉強会だけでなく、学校の授業や、結婚式の余興などでも活用できる機能です。
![qa1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337621/6d100bbd-2a4d-c86f-bf22-bbef129b758e.gif)

### 音声認識文字起こし機能
発表者の音声を自動的に認識してテキストとしてアーカイブします。
発表内容の文字起こしに使えます。
![onsei1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337621/84c00c94-3f3b-0a68-30ca-b962f22731f9.png)


### その他の機能
勉強会で活用できる機能が一通り揃っています。

- マイページ
- 非公開設定
- QRコードでイベント・スライドを共有
- イベント・スライド・Q&A編集機能
- フルスクリーン表示

## どうやって作ったか
### 既存サービスをフレームワークに
10月末にアイデアソンをやった時点でコンセプトは固まりました。
アイデアソンからハッカソンまでは後１ヶ月で、メンバ３名も本業があるので手はかけられない、どうやって作ろうか。
そこで、メンバの@Yuta_Fujiwaraが、<b>既存サービスのフレームワークを男前にも惜しげもなく提供</b>してくれました。
コメントやいいね、認証まで揃っていたので、その時点で基本機能はほぼできていました、、素晴らしい。
彼のおかげで、サービスを短期に形にできました。頭が上がりません。

### アーキテクチャ

![system4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337621/e38fd8f0-3f5c-4255-a56f-059106fbbaae.jpeg)

バックエンドは<b>Firebase</b>、フロントエンドは<b>Nuxt + SemanticUI</b>です。
この組み合わせを使ってみた感想として<b>「めっちゃ相性いい」</b>と思ってます。
余計な手間が少なく、サービスのロジック開発に集中できるし、思い通りに作れるので開発していて楽しい！
トラブルにハマって１日問題解決にかかってしまった、、ということが起こり難い気がします。
また、現状はFirebaseの無料枠に収まっているので、完全無料で開発ができているのも嬉しいです。

### バックエンド

#### Cloud Firestoreでリアルタイム性を追求
本サービスの肝は、発表者と参加者のリアルタイムなコミュニケーションです。
発表者のページを同期、参加者のコメントの同期、Q&Aの回答集計といったUXがリアルタイムに変化することで、ライブ感が生まれてくると考えているので、見せ方にこだわっています。
そのために、Firestoreの<b>onSnapshotメソッドを多用</b>しています。
自前のWebSocketで実装したら相当大変なことを、短いコードで実現できています。

ただFirestoreは使っていく中で「collectionを全件READして読み取り回数が膨大になる問題」が発生したり、「セキュリティルールどうする」「RealtimeDatabaseとの違いって何」などの議論が必要だったりして、まだ使いこなしを模索しています。

FJUGの[noriさんの記事](https://qiita.com/1amageek/items/d606dcee9fbcf21eeec6?utm_content=bufferecaae&utm_medium=social&utm_source=facebook.com&utm_campaign=buffer)などを参考にさせてもらいながら、勉強中です。

#### Cloud Functions でバックグラウンド処理実行
Firestoreのデータ更新のイベントをトリガーにするバックグラウンド関数として、コメント数の集計などで使っています。
今後は、データの登録をトリガに検索のインデックスを作る等でもっと活用したいと思っています。

#### 認証・ストレージ・ホスティング・分析もFirebaseでOK
- 認証はFirebase AuthenticationでGoogle認証とTwitter認証を利用してます。
既存サービスのものを利用したので開発レスでした。超便利です。
- サイトの公開はFirebase Hostingで。
- Firebase Storageに発表資料や画像のバイナリを保存。
- Google Analyticsをアクセス数の解析などのために導入。これから活躍してくれるはずです。

### フロントエンド
#### Nuxt.js・Vue.js
各メンバが利用経験が有り、コンポーネントを分けた並行開発がし易いNuxtをSPAモードで使用しています。
Vuexも使いやすいです（私はRedux苦手です）。
ライブラリを使った機能追加も容易なので助けられました。
本サービスでは以下を使っています。

- [vue-pdf](https://www.npmjs.com/package/vue-pdf) & swiper.js :
  スライドが中心のサービスだけに、スムーズな画面遷移＆ページ同期が必須です。
vue-pdfを使って発表資料を表示、swiperでページを送れるようにしています。
この仕組みを@tammaxが動かしてくれたので、行ける！となりました。
- vue-qriously:スライド・イベント共有のQRコード生成に使ってます。生成が速くて良いです。
- [vue-chart](https://vue-chartjs.org/ja/guide/):
アンケートの集計に利用。こんな感じで使ってます。

![chart.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337621/0ed0a989-1a86-6816-7927-dffa30ae18d4.png)


#### [SemanticUI](https://semantic-ui.com/)
「既存サービスで使っていていいよ」とのメンバのリードで採用。
使ってみるとdivタグのclass属性にUI要素を並べるだけでいい感じのUIができるし、iconも種類が豊富でかわいい。
個人的にはVue+Vuetifyより、Vue+SemanticUIの方が好みです。
SemanticUIについては[この記事](https://qiita.com/Yuta_Fujiwara/items/8abeda1b92dcaf505149)が詳しいです。


## チーム開発のためのツール
メンバ３名は全員本業で結構忙しくしているので、開発するのは平日の夜や休日になります。
使っているツール群は以下のものです。
一般的ですが、自分に取ってはバリバリ使うのはどれも初めてだったので新鮮でした。
今では、このツール群とMacとVSCodeが有ればどこでも開発できる、と思うようになりました。

### Slackでチャット
対面で会えないので基本連絡はSlackで。
GitHubにコミットしたら通知するように設定してます。

### GitHubでソース管理
Privateリポジトリで開発しています。
最初はmasterブランチ一本で開発していましたが、後に間違って上書きするのが怖くなってきて、developブランチでテストしてからmasterに上げる運用にシフトしました。

### Trelloでタスク管理
タスクを看板で見える化してます。今後の機能要望もここに蓄積しています。
![trello.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337621/e5477d1e-4f7d-2473-ab4b-8712ea890c9b.png)

## ハッカソン当日
### 風邪でダウン
そんな大事な日に、私は風邪でダウンしていました。
その週に会社を３日も休み、病み上がり状態だったのです。
また、休日にノコノコでかけて、風邪がぶり返すことも許されませんでした。

でも<b>SlideLiveが有ったので大丈夫</b>でした（＋Zoomも）。
自宅から、Zoomの画面を見て、SlideLiveの発表資料を見つつ、コメントを投入していました。
そして、一人でこれは行けると盛り上がっていました。

### ハッカソンをハックする
私達は、ハッカソンの参加者でありながら、各発表者にもSlideLiveを使って発表してもらう仕込みをしていました。
この作戦は大成功でした。
自分たち以外の発表でも<b>常にSlideLiveがアピールされている</b>状況を作り出すことができたのです。

ちょっとズルい作戦だったので、他の発表者の方には少し申し訳なかったかなと思いましたが、、（当日の発表者の方、すいません。）
狙ってやったというより、サービスの特性上、たまたまハマった作戦でした。

### 好評価

「SlackやTwitterで実況するより一体感がある」
「ページ遷移が連動するのいいね。ログイン不要なのも良い」
「Slidoと違ってスライドを確認できるのが良い」
といったコメントをいただきました。
スライドとコメントを統合して、一貫して見られるようにした所が良かったのかも。

### そして審査結果発表、、

<b>最優秀賞を獲得</b>できました！
私は画面の中で表彰されるメンバ２名を見て、誇らしい思いでした。

審査員の中島聡さんは私が本を愛読している方で、特に[エンジニアとしての生き方](https://www.amazon.co.jp/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E3%81%97%E3%81%A6%E3%81%AE%E7%94%9F%E3%81%8D%E6%96%B9-IT%E6%8A%80%E8%A1%93%E8%80%85%E3%81%9F%E3%81%A1%E3%82%88%E3%80%81%E4%B8%96%E7%95%8C%E3%81%B8%E5%87%BA%E3%82%88%E3%81%86%EF%BC%81-%E3%82%A4%E3%83%B3%E3%83%97%E3%83%AC%E3%82%B9%E9%81%B8%E6%9B%B8-%E4%B8%AD%E5%B3%B6-%E8%81%A1/dp/4844329944)という本が大好きで、今まで読んだ中でも５本の指に入る本です。
その中島さんに評価されたなんて、信じられない思いでした。

そして何より嬉しかったのが<b>SlideLiveを使って勉強会が盛り上がった</b>ことです。
自分たちの狙い通りに喜んでもらえたことは最高のご褒美でした。

当日の様子は以下から参照できますので、参考にリンクしておきます。
[SlideLive Firebase Startup #2 ー Pitch & Demo Day](https://slidelive.jp/event/?id=16e9b7ece1bc47a82b)
[noteのレポート 前編](https://note.com/singsoc/n/n37a67ae295f2)、[後編](https://note.com/singsoc/n/n3bdadb7ee5bb)

現場で祝杯を上げれなかったのは残念だったので、その後３人で打ち上げで祝杯を上げ、当日の話を肴に美味しいお酒を飲みました。

## チーム開発をやって思うこと
### メンバへの感謝

私自身は、普段は開発マネージャーとしてマネジメントを担当していて、「ここ数年コーディングしてないな」「最近どんな技術が流行っているのかな」という思いから、勉強会に参加し始めました。
半年ぐらい経って、一緒にサービスを開発する仲間ができて、開発したサービスをほめてもらえて、スキルアップもできて、「最高だな〜」と思っています。

今回、たまたま良い仲間と出会えましたが、それまでは悶々と勉強会に一人で参加して、懇親会であまり交流もできずに寂しく帰ることも多かったです。
ここでは、そんな<b>内弁慶エンジニアの私が一歩外に踏み出せた</b>経験は自信になりました。
僕と同じように社内以外のエンジニアとつながりがない、、😓と思っているエンジニアの方がいたら、是非後押ししたいです。

### チーム開発のメリットは大きい
それまでは個人でアプリ作ったりもしましたが、物になりませんでした。
チーム開発は以下のようなメリットがあると感じます。本当に有り難い。

- 開発したもののフィードバックがもらえて、改善サイクルが回る
- 励まし合ったり、あの人がここまでやったから自分もここまでやらなきゃ、と思って開発のモチベーションが持続し易い
- 人のコードを見るのが参考になる
- 詰まった時に相談できる
- 飲み会ができる

チーム開発についてはメンバの@Yuta_Fujiwaraが[noteの記事]
(https://note.com/fujiyama_yuta/n/n00054e32d808)で詳しく書いていますので、見ていただけるとうれしいです！

## SlideLiveの今後

### 「勉強会をライブに」を実現したい
せっかく頑張って準備した発表資料・プレゼンはその場限りではもったいない、とても良いコンテンツだと思いっています。
もっと多くの人の目に触れて、フィードバックを沢山もらえて、アーカイブが残る、<b>勉強会コンテンツの価値を最大化する</b>サービスにしたいです。

音楽のライブであれば、ファン同士が盛り上がったり、出演者と対話したり、DVDが出たりします。
勉強会もそんなポテンシャルがあると信じています。

そのために、twitterやSlackと連携で参加者を増やしたり、音声認識等のアーカイブ機能も強化します。
「勉強会ならSlideLive」が定着するような、デファクトのサービスになることを本気で目指して行きたいと思います。

### 最後に
FJUG、シンギュラリティ・ソサエティの方々にはこんないいイベントを企画していただいて、とても感謝しています。
その中で、SlideLiveのサービスに期待をいただいているので、それに応えてサービスを育てていきたいと思います。

長文読んでいただいて有難うございました。
是非使ってもらって、フィードバックいただけると大変有り難いです。