【個人開発】投票し放題の人気投票アプリを作りました【Vue × Firebase】

以前もあった、1週間でwebサービスを作る[web1weekというイベント](https://crieit.net/boards/web1week-202005)の第二弾です。今回のテーマは「Like」でした。
今回も参加させていただきました！滑り込みセーフ！

## 作ったもの

こんな感じの人気投票です。操作については特に説明はいらないと思います。
また争いが生まれてしまう……。

[https://like-ranking.web.app/](https://like-ranking.web.app/)
※ 一日の制限に達すると閲覧すらできなくなります。
![like-ranking.web.app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322882/8a2f97a7-abe3-1d06-b780-ac8b231a78ed.png)



## コンセプト

### あなたの熱意が票になる。

> あなたは好きなだけ投票することができます。
あなたの頑張りがそのまま票に反映されます。
あなたの成果はランキングで可視化されます。
あなたと共に戦う仲間やライバルが見えます。

人気投票というものは基本的には同一投票者による投票は1票までと決まっています。
ただ、「人気」を「愛され度」というなら、投票者の熱意が反映されないのはおかしいのではないだろうか。
某アイドルグループの人気投票はお金を積むことで熱意を示すわけですが、ここではクリックという時間と手間に置き換えることにしましょう。
そして、せっかく努力をするなら見返りというか、達成感のようなものがあるとなおよい。アイドルの例でいう「認知」のようなものを。


## **技術的なこと**

### **使用したもの**

- Vue-cli
- Firebase（Firestore / 認証 / Hosting）
- [DesignEvo](https://www.designevo.com/jp/)（ファビコン）

### Firebaseについて

機能上データベースが必要なのですが、Firebaseが手軽にバックエンドを実装できるということなので、これを機に手を出してみました。
匿名認証という、まさに私が欲しい機能があったのが最高でした。
データベースの形式がNoSQLというもので（聞いたことがある！）、今まで使ってきたものとは違ったので使い勝手に慣れませんでした。
でも、話で聞いていたとおり、デプロイがビビるほど簡単でした。

```console
yarn build
firebase deploy
```

だけでデプロイできる。強い。
リアルタイムでデータが反映されると書いていたので、まさか……と思ったら本当に反映されておもしろかったです。
[![Image from Gyazo](https://i.gyazo.com/d0330308aba31dd63143315c4ae2ea85.gif)](https://gyazo.com/d0330308aba31dd63143315c4ae2ea85)

## 作成記録

### 5/19 構想をメモ

そういえば企画のお題が発表されているはず！と思い出して確認する。
自分自身、「ボタンを押すと数字が増える」というのが好きだったので、なんとなくLikeの成分と絡めて、ボタン押し放題→投票→コンセプトという感じで

- 投票し放題
- ユーザーの投票数に応じたランキング

というコアの機能を決めました。
![IMG_20200524_113427.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322882/bcff8b8d-7ee0-284b-3cf3-dae20e768792.jpeg)
関連付けを使いたくないなあと思ってこういうデータベース構造を考えたのですが、これは非常によくなかった。
ちなみに、rankings（rightName, rightCount, leftName, leftCount）, users（uid, name, leftCount, rightCount）という感じの構成でした。

### 5/20 Firebaseの設定

3時間くらい。
Firebaseの登録をしてデプロイをしようとしたが、HelloWorldのデプロイがうまくできなかったので一旦諦める。

### 5/23 無制限投票機能

13時間くらい。
思い立って新しく作り直してやってみたところ、何のことはなくあっさりとデプロイができたので、作成開始。
ググりながらQiitaと個人ブログと公式とを行ったり来たりしながらデータを渡す。データが渡せればあとは表示するだけ。
久しぶりにCSSを触ったので楽しかったです。フォントやボタンは[モロゾフプリン対決のサイト](http://www.morozoff.co.jp/puddingbattle/second/)を参考にしました。このボタンがまさに押したくなるボタンのデザインで、やっぱり企業サイトはすごいと思いました。

### 5/24 ユーザー認証、ユーザーデータの表示

11時間くらい。
ユーザー認証（アクセスした時点でログインしてuserデータを登録をする）自体は前日の最後にできていたので、名前変更機能やランキング部分を作りました。
そして、なんとか公開に至りました。
デプロイして一息ついた後に風呂から帰ってきたら制限で落ちていたので、まじかと思いました。公開して終わりにしようと思っていたのですが、機能としてわりと致命的なので、まあできるだけのことはしようと思いました。

### 5/25 リクエスト部分の修正

4時間くらい。
データ制限が解除された5時頃から作業を開始しました。
元々、投票したときにrankingとuser両方のデータ更新をしたり、並び替えの仕方がよくわからなかったのでランキングの各コンポーネントでそれぞれusersを取得したりしていました。

そしていろいろと試していると、途中でデータベースの中身をいじらないといけないということに気づきました。具体的に言うと、全てのユーザーに`leftCount: 0`のようなカラムを手作業で入れなければならないということに気づきました。
そして、目の前でカウントが増えていくのを見ていると胃が痛くなりそうだったので、一旦非公開にしました。

今までJavaScriptでロジックを書くということをしていなかったので、並べ替えやデータ集計などに苦戦しました。SQLで引っ張ってこれないの面倒だ！
あと、データバインディングで死にかけました。sortって破壊的メソッドなんですね……。

結果的に、rankingはなくして、きのこたけのこ限定にしました。usersのleftCount, rightCountをそれぞれ集計して投票数として表示しています（本来は元々こうするべきなんだろう）。


## おわりに

最初のデプロイに挫折して今回は諦め気味だったので、提出できてよかったです。

こういうサービスというのはいろんな人に使われているのを見るのが醍醐味でもあると思うのですが、企画を通していろんな人の目に触れられることができたのでとても嬉しかったです！！
このような機会を設けてくださった主催者のだら様に感謝申し上げます。

そして、私がtimesに進捗を挙げるたびに褒めてくれたり、テストプレイ？に協力してくれたRUNTEQの皆さんも本当にありがとうございました。

ちなみに私はきのこもたけのこもおいしくいただく反逆者です。

### 課題

- Firebaseとのつなぎ込みがコピペマン。多分、別ファイルに切り出したほうがいい。
- ~~ranking has_many usersのイメージだったが、できていない。データのネストができることに後で気づいた。~~→rankingは消した。
- セキュリテイルールは穴だらけです。
- ~~リクエストの仕方は絶対もっとうまくできるはず。~~→これ以上改善するのは私には無理。
- ローディングがあけるタイミングがちょっと速い。
- リクエスト上限に到達したときにエラーメッセージを表示したかったが、やり方がわからなかった。
<img width="1184" alt="スクリーンショット 2020-05-25 0.18.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322882/54d6d843-f113-581d-7deb-40a88ce2bb0d.png">
NaNてこったい。