Nuxt.js(SPA)+Firebaseで積読用の読書管理サービスを作ってみたときにハマったこと...

Nuxt.jsとFirebaseで作っていたWebサービスを7月末にリリースしました!!
開発中にいろいろとハマったので、そのポイントを整理してみました。

内容的にはドキュメントをよく読めば書いてあることばかりですが、
作った or 思いついた後に、ドキュメントを見つけるので、手戻りが多く...
あらかじめ、知っていたら良かったなと思う点をまとめています。


## 作ったのはこんなサービスです！

積んでる本の総額がわかる読書管理サービス
『[積読ハウマッチ](https://tsundoku.site)』

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/07938d40-accf-b227-6fcb-4e5f4bff20c7.png" width="40%"/>

積んでいる本を登録する書籍管理サービスで、
すこし違うのは、積んでる本の総額がわかること。

積んでるだけの本の総額がわかるとすこしは読む気になるかなと(*´ω｀*)

シェアしたときに金額が表示されるOGP画像も用意していて、
どれくらい積んだかを公開することができます!!

<img width="401" alt="スクリーンショット 2019-07-26 10.01.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/fb623896-53c7-5e3e-ffc2-5f7ab4d81450.png">

## 全体の構成はこんな感じ

<img width="845" alt="スクリーンショット 2019-08-13 23.06.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/3ab45cc9-0a03-5a5b-8297-a6f5af1e9c0d.png">

- SPAモードのNuxtアプリをFirebase Hositingにデプロイ
- データベースはFirestore
- OGP生成のためにCloud Function for Firebase+ImageMagic
- OGP用のHTML生成でCloud Function for Firebase
- 外部APIを利用したいのでZEIT NOW経由でのAPIを用意

特に**書籍検索用にトークンを用いた外部APIを利用**したいのと、
**金額などを更新したいためOGP画像の生成**をしたいというのが必要な感じです


## わたしはここでハマリました...

ドキュメントやいろんな記事も書いてあるのですが、あとで気づくことが多く...
ハマったポイントをまとめています。

#### Cloud Function for Firebaseの無料枠だと外部APIにアクセスできない...

当初は無料枠でなんとかすることを考えていて、書籍検索用の外部APIを利用したいなと。

[こちら](https://firebase.google.com/pricing/?hl=ja)に書いてありますが、無料のSpark プランでは、
Googleサービス専用で外部APIにアクセスしようとするとエラーになってしまいます。。

<img width="500" alt="スクリーンショット 2019-08-13 23.49.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/9ab414a2-f48d-5fa0-dc6f-4c7cf677be09.png">

実際に動かしはじめたときに、エラーメッセージをみて気づいたので、手戻りが...

しかし、発行されたトークンを利用しているので、Nuxt.js側には配置しづらく。

そこで利用したのが[ZEIT NOW](https://zeit.co/now)。こちらは外部アクセスも可能なので、
API部分だけ、こちらを利用するようにしました。

NOWに関する内容は、こちらにまとめました。
- [Webアプリやサービスを簡単にクラウド化できるZEIT/nowでWebAPIを作ってみた - くらげになりたい。](https://www.memory-lovers.blog/entry/2019/05/13/234009)

#### Hostingの該当パスにHTMLがあると、Functionへのリライトが効かない...

当初はOGP画像を表示させるため、メタタグのみのHTMLを返すFunctionを用意していたんですが、
`nuxt generate`で生成したファイルをHostingに配置した先とHostingのりライトが同じため、
うまく処理がされず。。

[こちら](https://firebase.google.com/docs/hosting/url-redirects-rewrites?hl=ja#section-priorities)に記載されていますが、ホスティングの優先順位があるよう。。

> 異なる構成オプションが競合することがあります。競合が発生した場合、Firebase Hosting からのレスポンスは次の優先順位に従って決定されます。
> 1. 予約済み名前空間（/__*）
> 1. リダイレクトの構成
> 1. 正確に一致する静的コンテンツ
> 1. リライトの構成
> 1. カスタムの 404 ページ
> 1. デフォルトの 404 ページ

これを見ると、`正確に一致する静的コンテンツ > リライトの構成`なため、
リライトで設定したFunctionが呼ばれず、うまく動作していないように見えた感じ。。

解決策としては、静的コンテンツがないURLに対してリライトを設定し、
Nuxt.jsのvue-router側でリダイレクトするように対応。

動的パラメタの例ではありますが、具体的にはこちらにまとめました。
- [Nuxt(SPA)+FirebaseでSEO！OGP！: 特定のパスだけheadだけ返すやつ - くらげになりたい。](https://www.memory-lovers.blog/entry/2019/08/07/150000)

#### serverMiddleware/nuxtServerInitはSPAで使えない...

こちらは名前の通りなのですが、SPAの場合、サーバサイドで実行されるものは全部使えず。。
当初はSPAではなくSSRを利用する予定で処理を書いていたのですが、
FunctionsでSSRを実行すると遅いので、SPAに。。

切り替えの際に、serverMiddleware/nuxtServerInitに書いてた部分が実行されず、
思いの外、修正に時間がかかってしまいました。。

いろんな記事で紹介されていたりしますが、SPAで使えるかどうかなど、
あらかじめ確認しておくと良さそうです。

#### FunctionでImageMagicを使うとCPUをすごく使う...

Cloud Functionsの上限で気にしていたのは、呼び出し上限だけだったので、
エラーが発生したときはすこしびっくり...
CPU秒やトラフィックのGB秒の上限も[こちら](https://firebase.google.com/pricing/?hl=ja)にちゃんと書いてあります...

特にImageMagicを使うとCPUをすごく利用するため、
テスト実行をしすぎないようにしたり、不要なときに実行されないようにする工夫など、
注意が必要だなと、上限に達してから気づきました...


# おわりに

いろいろと詰まりつつでしたが、やっとリリース!！
積読総額ランキングや人気の本などもあるので、よかったらあそんでもらえれば!!

積んでる本の総額がわかる読書管理サービス
『[積読ハウマッチ](https://tsundoku.site)』

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/572d4947-f40b-e4dc-1c9c-bc584cd2a66c.png" width="25%"/>