【入門編】Vue.jsとFirebaseでアプリをPRする掲示板を作る

# Vue.jsとFirebaseで爆速でアプリをPRする掲示板を作ってみた
現在、業務委託としてMikatus株式会社にてお世話になっております。
主に税務システムのサーバーサイドの開発を担当しています。
今回はMikatus株式会社のアドベントカレンダーに参加させてもらうことになりました。

自分、めちゃくちゃ硬派なので他の人みたいに面白い記事は書けませんがお付き合いいただければと思います。

非エンジニアの方が読んでも楽しめるように、文章の中に心の声と実際に出た声がありますが、
事実を基にしたフィクションです。
自分、硬派なジェントゥルマン（紳士）なんで。
硬派ですが物腰とかマシュマロくらい柔らかいんで。汚い言葉とかまぢ無理。

## 初めに
本記事ではアプリを作りにあたってハマった点などのノウハウを記載します。

Vue.jsやFirebaseについて技術的なことについては書籍や多くのWebサイトで調べたレベルでしかプログラムは作成していないため、
ご自身で調べていただくか、Githubにソースを公開するので記事で気になった所をコードで確認していただくか、
詳しく解説している方が使い方など書かれているので調べてみてください。

自分が困った時に参照したサイトやQiitaのページは最後に参考として書いておきますので
そちらを参照してください。


## アプリを作った経緯
普段の業務ではサーバーサイドでJavaの開発を行っています。

**心の声(๑•̀ㅂ•́)و✧**「この業界に入って早十数年、、、このままぬくぬくとJavaだけやってて大丈夫だろうか」

**心の声(๑•̀ㅂ•́)و✧**「そもそもJavaだってよくわかってないのに、、、、はぁ、、、将来が不安だ」

**心の声(๑•̀ㅂ•́)و✧**「やっぱりこのままじゃダメだ、これから先を少しでも生き抜くために今までフロントエンドとは無縁だったけど新しい知識の一つとしてVue.jsを学んでみよう！ついでだからFirebaseも一緒に覚えてみよう！」

**実際に出た声**「うぇ〜い、とりまストロングゼロでも飲むべ」

> 【参考】
> ※フロントエンド：簡単に言うとウェブでみんなが実際に見えてる画面を作る人
> ※Vue.js：画面を良い感じに作れちゃうイケイケな言語の一つ。めっちゃパリピ属性だと思われる。
> ※FIrebase：Google先生が提供しているWebアプリの開発を便利にしてくれる四次元ポケット的なツール達の総称

そんな流れから自分磨きプロジェクトの一貫としてアプリを一つ作ってみようと考えました。

**実際出た声**「めんどくせぇ。。。。」

~~毎日アルコールを摂取しないと生きていけない大病をわずらいながら、~~１日１時間ほど勉強と実験を繰り返して２週間くらいで形になりました。
ちょくちょく仕様を変えたり、細かい部分も含めると約１ヶ月（約２０時間）ほどでした。

日本酒をキメてハイな状態のコードもあると思います。
エ○カ様系のキマリ方はしてなかったのでしっかり動くコードは書けましたが、もっと良い書き方があったり、
Vueのお作法には則っていないかもしれません。

良い書き方やバグを見つけてくれたらこっそり教えて下さいね。
とりあえず、お陰様で毎日元気にお酒を美味しく頂いてます。

**心の声(๑•̀ㅂ•́)و✧**「（趣味でやる分には）Vue.js楽しい！Firebase便利！」

**実際に出た声**「べ、別にこんなんでVueのこと好きになったりしないんだからね！勘違いしないでよね！」

はい、出ました、非常にレアな硬派ならではのツンデレ。
日本酒でばっちりキマってなければ見ることはできないでしょう。

結構感覚で触れる部分が多くて（何かしらの言語でプログラムを触ったことある人であれば余計に）
ツンデレしちゃうくらい手を動かし始めるとサクサク作れるのが印象的でした。

そんなこんなで、多分爆速でがんばれば２〜３日くらいでできるかもです。
仕様考えてる時間の方がおそらく時間がかかると思います。

とりあえずCRUDは一通り出来た方がいいなと思ったので投稿サービスが良いと思って作りました。
[CRUD - Wikipedia](https://ja.wikipedia.org/wiki/CRUD)

**考えるな！感じろ！** 的な精神で動かしまくるのが一番手っ取り早いです。
修正したら自動的に画面の表示が変わるので毎回ビルドの手間がないのも早く作れる要因の一つです。

## アプリ紹介
アプリケーション名：あぴる
[あぴる〜アプリPRサイト〜](https://apiru-prod.firebaseapp.com/)

アプリケーションをPR（アピール）するためのアプリとして「あぴる」を作りました。
本記事のように勉強しながらアプリを作成している人が他の人に触ってもらえる場になれば良いなと思ってます。

**心の声(๑•̀ㅂ•́)و✧**「個人開発したク○アプリだってどんどんアピールする場があった方が面白いよね！やる気でるよね！」

**実際に出た声**「あざまる水産よいちょまる！！帰りにタピるわ」

硬派な自分としては人前で一生口にすることもない言葉も何かを作り上げた時はテンションが上がっちゃうもんですね。
多くのエンジニアに共感してもらえると思います。

口に出さずとも若者のトレンドにアンテナを貼っておくことはシャレオツなオトナの嗜みだと思ってます。
人に見られたらもう生きていけません。硬派ですから隠れてやる技術が試されます。

## 作成したコード
コードはこんな感じです。お作法とかよくわかってないので参考になるかわかりませんが、、、
[GitHub - yusuke0511/apiru: アプリケーションをPRすることができるWebアプリケーション](https://github.com/yusuke0511/apiru)

## 開発環境
* PC
MacBookPro 2018モデル
* エディタ（IDE）
Visual Studio Code
* 動作確認
【PC版】Google Chrome
【モバイル版】iPhone11 Safari
* その他
iTerm2

## 使用したもの
* Vue.js
* Vuetify (マテリアルデザインのUIフレームワーク）
* Firebase (サーバー側　mBaaS)
* 
上記の他にvueのプラグインを色々使用していますが、こちらはGitHubのReadme.mdを参照してください。

## 機能一覧
* ログイン認証（ [Authentication](https://firebase.google.com/docs/auth/web/start?authuser=0) (Firebaseの機能))
* データの登録・更新・参照・削除（ [Cloud Firestore](https://firebase.google.com/docs/firestore/quickstart?authuser=0) (Firebaseの機能)）
* 画像のアップロード( [Cloud Storage](https://firebase.google.com/docs/storage/web/start?authuser=0) (Firebaseの機能))
* 一覧表示(Vuetify)
* MyPage機能(Vuetify)

ざっとこんな感じでシンプルです。
一覧表示で検索ができるようにしていますが、こちらはVuetifyの機能で実現できたので独自に作り込まずにできました。

## 苦戦した所
### マテリアルデザイン
Vuetifyはマテリアルデザインのコンポーネントのフレームワークですが、そもそもマテリアルデザインって名前を初めて知った感じだったので結構悩まされました。

**心の声(๑•̀ㅂ•́)و✧**「ふむふむ、なるほど、全然わからん」
**実際に出た声**「ふむふむ、なるほど、全然わからん」

何度か心を折られかけましたが、Vuetifyのサイトではサンプルの動作確認とかできるので何度も動かしながら、そしてサンプルをベースに色々いじりまくってからイメージを掴み実装しました。
アプリ作成の多くをここの時間に費やしたと思います。

**「ちょっ、Vuetifyパイセンってちょっと使いにくいっすよねｗｗまじパネェっすわｗｗｗｗでも使えると表の表示とか秒でやべぇっすｗｗｗ」**

こんなイジリ方しちゃダメ絶対

私は硬派なのでもちろんお笑い的なイジり方は致しません。
漢たるもの背中で語れ的な感じです。

逆にVuetify先輩は優しくていじられても深い懐で受け入れてくれる姿がまさに漢です。

Vuetify先輩の**「お前は黙ってろ。表示に関しては俺に任せておけ」**って言葉には痺れました。
まぁ、言わせてるのはプログラムを書いている私なのですが、先輩のまっすぐな所、本当にかっこいいです。

たまに背中で語られすぎて意味不明に陥ることもありますが、そこは先輩の愛嬌なんだと思います。

非エンジニア向けに超絶簡潔に説明すると、cssというのは画面のデザインを定義するものです。
cssというファイルに「名前を入力する場所はここに、こんな感じで置いてね」みたいなことを定義します。

もちろん日本語ではないので全くプログラムを書いたことのない人にはちんぷんかんぷんだと思いますが。
硬派な自分としてはデザインの定義というもの自体にセンスがなく、またcssには（場合によっては）定義を大量に書く必要があるので結構cssでデザインをしていくと大変になっていきます。

実際のところ、cssをゴリゴリ書かなくて良いのでcss恐怖症の自分には結構助かりました。
未だにそんな慣れてないですが、触り始めた初日に比べたらだいぶ進歩しました。
レスポンシブ対応してるのも魅力的！

**心の声(๑•̀ㅂ•́)و✧**「このデザインcssで作れって言われたら無理だけど、コンポーネントを置いていく感じでできるの素敵！Vuetifyありがとう！！」

**実際に出た声**「OK、Google！女の子にモテるデザイン教えて。あと美味しい日本酒。」

硬派だとナンパとかできないんでGoogle先生に頼るしかありません。
誰かモテデザインの正解を教えて下さい。
硬派もなかなか悩みは尽きません。
実際イケてるデザインのサイトは人気でますからね。羨ましい限りです。

硬派な私としては阿部寛のホームページくらい漢でありたいものですが、、、、

### vuerouterを知らなくて次ページに行っても画面が先頭に行かなかった
ググったらすぐ見つかったので解決したのですが、最初はSPAってそういうものなのか・・・・と絶望しました
んなわけないやろ！と思って調べたら一瞬でした。まぢ秒でみつかったしウケるー笑
vuerouterありがとう！

### データの受け渡し
**心の声(๑•̀ㅂ•́)و✧**「データの受け渡しくらい余裕だろ、、、、あ、、、あれ、、、、orz」

**実際に出た声**「今夜は濃いめハイボールな気分だな・・・・」（飲んでそのまま寝落ち）

MyPageで登録した内容を編集できるのですが、データの受け渡しでちょっと苦戦しました。
データの受け渡しとは画面Aで表示しているものを画面Bに渡したいということです。
画面Aで名前を入力したら画面Bで入力した名前を渡して表示したい場合とかに使います。

色々調べて出来てしまえばそう大変なことではなかったのですが、親子関連のコンポーネントと親子関連のないコンポーネントで渡し方が違うのと、編集画面をモーダルにしたので内容の切替で四苦八苦しました。

**心の声(๑•̀ㅂ•́)و✧**「なるほど、親子関係の有無でやり方が違うのか！設計の見直しした方良い所もあるな！」

**実際に出た声**「そ、そんな、、、うちのジョンが俺の子じゃないなんて、、、、、」（酔っぱらい）

硬派と言えばドロドロの人間関係に巻き込まれることもあるでしょう。
プログラムを通してイメージトレーニングを欠かすことはできません。
いつ何時いかなる状況でもうろたえる男になってはいけません。常に硬派な男であり続けるために必須要素です。

ちなみに妻の名前はトーコン・ジェイミー・ヤナイの設定です。20代前半の色白ロシア系アメリカ人です。

今回のケースで言えば誕生日プレゼント（データ）を渡そうと思ったら、息子のジョン（コンポーネントA）が愛するジェイミー（コンポーネントB）との子供ではなかったことが発覚したことから、ジェイミーに誕生日プレゼントの受渡しを拒否されてしまったわけですが、法的な手続き（Vueインスタンス）を経由して渡す方法を学びました。
※例がわかりにくすぎる・・・・語彙力ください

これでいつドロドロの人間関係に巻き込まれても安心です。

その他にもこちらのサイトを見ながら無事に実装できました。
[【Vue.js】コンポーネント間のデータ通信について図解 | とものブログ](https://se-tomo.com/2018/11/03/vue-js-%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E9%96%93%E3%81%AE%E9%80%9A%E4%BF%A1/)
[Vue.jsで動的にモーダルウィンドウを表示する - Qiita](https://qiita.com/asaokamei/items/c45becfc8c706e70c63c)

### iPhoneの画像回転問題
**心の声(๑•̀ㅂ•́)و✧**「よし、画像アップロードができたぞ、、良い感じだ。そうだスマホで見てみよう！！えいやっ！、、、、あれ？」

**実際に出た声**「iPhoneで撮った○○とのツーショット写真が横なってるとかマジ○すぞ」

硬派が故、自分よりも相手が横になってしまったことで激高してしまったようです。
人の繋がりとか何よりも大事にするのが硬派な漢ですからね。
ましてや最近のWebサイトはほとんどがスマートフォンからのアクセスなのでこの問題は結構悩みました。

アップロード機能自体はVuetifyのアップロードコンポーネントで簡単に実装することができましたが、iPhoneで撮影した画像は90度回転して表示される問題がありました。
blueimp-load-imageというプラグインを使用して解決することができました。

[【簡単】画像選択時のプレビュー表示とExif対応【JavaScript-Load-Image/Vue】 - Qiita](https://qiita.com/su_mi1228/items/f8f729a29f0b980f7e32)

あぴるでは画像を選択した際にプレビューを表示するのですが、その後に回転した状態で画像をFirestorageにアップしないと登録後の一覧画面でまた横になってしまう問題とぶつかりました。
データ選択をした際に下記のメソッドを呼び、回転させたデータをFileクラスを生成してデータを持つことで回転した画像を保存することができました。

```javascript
displayImage(file, options) {
      loadImage(
        file,
        async (canvas) => {
          const data = canvas.toDataURL(file.type);
          // data_url形式をblob objectに変換
          const blob = this.base64ToBlob(data, file.type);
          // objectのURLを生成
          const url = window.URL.createObjectURL(blob);

          this.uploadedImage = url;
          this.file1 = new File([blob], file.name);
        },
        options
      );
    },
```


## 今後の追加機能
今回はアドベントカレンダーに向けてアプリを作ったので簡素なサイトになってしまいましたが、もっと便利な機能を引き続き作っていこうと思います！
* TwitterやFacebookでログイン（Firebaseの認証設定を追加）
* SNSへのシェア機能
* いいね機能の実装
* アクセス数ランキング

## 実際に作ってみた感想
**心の声(๑•̀ㅂ•́)و✧**「まだまだ初心者だけど、普段使わない技術を勉強できて楽しかった。もっと色々工夫できるはず！もっとモチベーション上げてがんばるぞ〜！」

**実際に出た声**「拙者、働きたくないでござる」

硬派だからと言って最強な人間ではありません。たまには仕事を忘れてゆっくりしたい日もあります。
ましてやエンジニアという職業は流行り廃りが早いですからね。
私のような硬派な人間でもしっかりと波に乗らなくてはいけません。
硬派な私でも「良い波のってんね！」と言われるよう技術を吸収する必要があります。
身体も心も硬派ですが、柔らかい柔軟性のある頭は持っていないと開発では困ってしまうことも多々あります。

普段からサーバーサイドを作ってる身としてはログイン機能とかアップロードとか色々なことを実装するのは時間がかかるしめんどくさいなと思っていたのですが、今回初めてFirebaseを使うことでフロントエンドの動きに集中して書くことができたのはすごい楽に感じました。
フロントエンドの技術は移り変わりが早いのでVue.jsもどこまで寿命が持つかわかりませんが、しばらくは盛り上がってくれそうなので、今回のようなアプリを作ったり、改善したりチャレンジしていきたいなと思いました。

サーバーサイドを作るとなると、レンタルサーバーを借りたりやることが多いのに対してFirebaseにアプリをデプロイすればバックエンド側はほぼお任せできるので小規模な開発では恩恵が大きいと感じました。

がっつりバックエンド処理が必要な場合はログイン機能だけ使うとかデータベースだけ使うなどの選択もできるので良いと思います。

## 最後に
文章の中に心の声と実際に出た声がありますが、事実を基にしたフィクションです。
自分、硬派なんで。
※大事なことなので二回言いました。

硬派が故、非常に硬い文章となってしまってかたじけない。
最後まで読んで頂き感謝感激でバイブスぶち上がりです。まさにポンポンポンって感じです。

Vue.jsとFirebaseを使用することで学習コストを低く色々なことができるのでこれを気に是非使ってみてください。
今後も引き続き色々な知識を吸収しながら「あぴる」のバージョンアップや、新しいアプリの開発を進めたいと思います！

そして、最後まで読んでいたきありがとうございました。
最後まで読んだ自分へのご褒美にギロッポンでパーリーピーポーうぇいうぇいしちゃってください！
何度も言いますが私は硬派なので静かな家で漢らしく焼酎のロックで寡黙に過ごそうと思います。

Twitterでコメントして頂いても大丈夫です！
[@yusuke_celalink](https://twitter.com/yusuke_celalink)

それではまた。

## 参考
記事内で紹介した記事意外にも様々なサイトを参考にさせていただきましたので紹介いたします！
[JS Firebase Authentication の覚書 ① メールアドレス認証 - WebTecNote](https://tenderfeel.xsrv.jp/javascript/3606/)
 [Firebase入門 フリマアプリを作りながら、認証・Firestore・Cloud …](https://employment.en-japan.com/engineerhub/entry/2019/06/07/103000) 
 [Vue.js 2.0 でログイン (vue-router で認証が必要な URL を定義)](https://qiita.com/takatama/items/05e9fbc7199cde4caf60) 
 [体で覚えるVue.js - ディレクティブ編 〜 JSおくのほそ道 #023](https://qiita.com/hosomichi/items/25041c1d46452de84aa6) 
 [Vue-routerを使って、SPAをシンプルにはじめてみる](https://qiita.com/567000/items/d6a7c694a370dc92e774) 
 [かゆいところに手が届くvue-routerの機能](https://qiita.com/nishinoshake/items/9ce7d6a04ffb82755ae1)