[Vue.js] 生徒を重複なしにランダムで選ぶwebアプリ [Randomer]

# はじめに
どうも、教育関係者と話すことが多く、教育現場で使えそうなアプリを作りたくなった人です。

今回紹介するのは、そんな教育アプリの第一号、事前に登録した生徒たちから重複なしにランダムで選出するアプリ、通称 [Randomer](https://randomer.zscode.net/) を紹介します。

後半に技術的な話をしているので、そっちもどうぞ。

https://randomer.zscode.net/

# 主な機能

- 生徒をランダムに選ぶ

これだけです。


# 使用方法

ページを開くと、こんなダイアログがでてくるので、**Google**でログインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974385/a8ee8a1a-c11a-547a-70bf-2989e84d0040.png)

## クラス・生徒の追加/編集
PCは上のメニューバーにある [Edit] と書かれた場所を、
スマホ版は左上にある [≡] を押し、 [Edit] をクリックし、
エディットページに移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974385/6ab265a7-60d1-f2a6-f398-3fdda066bf0d.png)

画面右下にあるこのボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974385/038b93b7-974c-2df2-0201-35d04dcc9906.png)

出てくるダイアログに、追加したいクラスの名前を入力、Addを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974385/11bbfac9-c64a-bfde-8120-827f75cf7ac7.png)

そうすると、こんなカードが出てきたと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974385/94bb7a5d-6dc2-7b4a-19ab-0e3bbb1a3f9c.png)
このカードの [USE THIS] をクリックします。
そうすると、このように表示が切り替わります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974385/ffced67d-9059-8196-25ae-bb004e8f4377.png)

初期値の [A, B, C, D]が入っているので、全部削除します。
そのご、追加したい名前を [生徒名] の中に記述し、Enterキーか [Add] ボタンを押し、追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974385/8ce0e8f5-d938-3e48-ccb3-ce7cf2087fb0.png)

## ランダム選出
メインの機能を紹介します。

Randomページに移動します。
編集の時と同じ要領で、クラスを選択します。
そうすると、このようにボタンが四つ表示されると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974385/f542152d-1ebc-106a-4830-ecb33661e5e8.png)

- **CHOOSE**：ルーレット開始 ランダムで誰かが選ばれる
- **SAVE**：誰が選ばれたかの情報を保存する
- **SHOW LIST**：既出リストが表示される （誰が選ばれたか一目でわかる）
- **HIDE LIST**：既出リストを隠す

既出リストは、全員選ばれるとリセットされます。

これで、あの理不尽な選ばれ方をされなくて済みますね！


# 仕組み

## データベース
データの保管は [Firebase Realtime Database] で行っています。
Sparkプラン(無課金プラン)なので、同時に100人までしか使えません

データベースを利用したアプリの公開経験が無いので、どれくらい使用されるか一切わかりません。
なので、リリースして少したってからBlazeプラン(課金プラン)に移行するか検討します。

## ランダム選出
ランダムに重複せずに選出する方法は、選ばれていない人のリストを作成し、その中から選んでいます。
すでに選ばれた人たちは表示できるようにしようと思い、既出リストがクラスのデータの中に含まれています。
未出リストはその既出リストと生徒リストの差分を入れます。
これにより、まだ選ばれていない人たちだけを選出することができます。


```javascript
const members = ['a', 'b', 'c', 'd', 'e']
const before = ['a', 'b', 'd']

const after = members.filter(
  m => before.indexOf(m) === -1
)

console.log(after)
//  ['c', 'e']
```

⇧このコードを使って、未出リストを作成しています。

```javascript
const index = Math.floor(Math.random() * after.length)
const choose = after[index]

console.log(choose)
// c
```

⇧このコードで、未出リストから一人ランダムに抽出

## ちょっとした演出
ただ表示されるだけじゃつまらなかったので、ちょっとした演出も＋

選出されるまでランダムで関係ない名前も表示するようにしています。
これは、生徒全体からランダムに選んでいるので、未出リストに一人だけしか入ってなくて、ずっと一人だけしか表示されないという現象が怒らないようにしています。


# スタックしたこと紹介

## MongoDBはVue.jsじゃ使えない

node.jsでは使用可能だったから、Vue.jsでも使えるんかなと思ったら、Vue.jsの仕様上使えなかった。
いろいろ試行錯誤して、無理やり使おうとしてたから、そのせいで超時間食った。

## Firebase OAuthが使えない ?!
正確には、読み取れるはずの情報が読み取れませんでした。
これは、Firebase上で作成した認証情報のスコープが設定されていなかったのが原因でした。

[Google Cloud Platform] > [APIとサービス] > [OAuth 同意画面]
`（プロジェクト名は、firebaseのプロジェクト名と同じ）`
の [project-xxxxx] と書いてある場所の右側にある [アプリを編集] をクリック

[2 スコープ] の [スコープを追加または削除] を押し、
[.../auth/userinfo.email] [.../auth/userinfo.profile] [openid] を追加してあげると、認証情報を取得できるようになります。

## Firebase Realtime Databaseのrule設定
これは、他の問題に比べ、あっさり解決しました。
[ドキュメント](https://firebase.google.com/docs/database/security?hl=ja) を読めば大体理解できます。

https://qiita.com/mironal/items/b93742e8ef72b3268beb

こんな記事もあります。
ドキュメントを読んでもわからなかったので、自分はこれを使いました。

## Firebaseのバージョンは明記してくれぇ、、、（切実）
これ、firebaseを使う上で、まじで困った
「コピペしてるだけなのになんでエラーが出るの？？？」
という問題が起きていました。

```shell
npm install --save firebase
```

でインストールされるのは、Ver.9で、ドキュメントで使われているのはVer.8だった。

https://qiita.com/kawa31/items/77443eb231405a2bbf7d

この記事では、import文をVer.9仕様に書き換えているが、自分は

```shell
npm install --save firebase@8.10.0
```
として、Ver.8をインストールしました。

# 最後に
このアプリは素人が作ったものです。
もちろん、使いづらいのは理解しています。

気が向いたらでいいので、ご意見・ご要望を `アプリ内のFeedbackページ` もしくは `この記事のコメント欄` でください。
修正できるものは修正し、今後のアプリ制作でも参考にします。