【JAMstack】Next.js × Firebase で JAMstack なブログサイトを作る②［ブログサイト］

<!-- ======================================================= -->
# 概要
<!-- ======================================================= -->
本記事は、[【JAMstack】Next.js × Firebase で JAMstack なブログサイトを作る①［概要］](https://qiita.com/nemutas/items/555c75f4473f605123fc)の続きとなっています。

本記事では、ブログサイトの記事を**Firebase Storage**から取得する処理を実装します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358498/007674c4-a205-d93e-97ff-e1febface8b5.png" width="500px">

<!-- ======================================================= -->
# ブログサイトの雛形の作成
<!-- ======================================================= -->

ブログサイトは、Next.jsの公式チュートリアルをもとに作成します。
また、Next.jsを開発しているVercel社のHostingサイト（Vercel）にデプロイします。

https://nextjs.org/learn/basics/create-nextjs-app/setup

ドキュメントは全て英語ですが、日本語で解説してくださっている動画があります。
たいへんわかりやすいので、こちらを見ながら作成するのをおすすめします。

https://www.youtube.com/watch?v=F77RUjHZEAc

※ 動画のシリーズの番外編として、最後にGitHubにアップロードしているMarkdownファイルを取得する処理を追加していますが、今回の実装では不要です。
また、すべてのファイルをTypeScriptに対応させます。[こちら](https://nextjs.org/learn/excel/typescript/nextjs-types)を参照

<!-- ======================================================= -->
# Firebase プロジェクトの作成
<!-- ======================================================= -->
ブログサイトの記事を、**Firebase Storage**から取得するために、Firebaseプロジェクトを作成します。
作成手順は、以下の記事の**Firebaseプロジェクトの作成**を参考にしてください。

https://qiita.com/nemutas/items/330cab413bccd9b2e096#firebase%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90

※ リージョンの選択がある場合は、すべて<font color="Red">**asia-northeast1**</font>で統一します。

プロジェクトを作成したら、**Storage**を作成します。

<!-- ======================================================= -->
# Storage からデータを取得する
<!-- ======================================================= -->
Next.jsのSSG・SSRでFirebaseを扱う場合の**罠**として、Firebaseの処理がサーバーサイドで動作することになります。
サーバーサイドでFirebaseの処理をするためには、**firebase-admin**を使用します。そのためには、Firebaseから**秘密鍵**を取得する必要があります。

取得の方法は、以下を参考にしてください。

https://qiita.com/centerfield77/items/799f2840f48221c2f84d

https://qiita.com/centerfield77/items/49b029d4d1618dfeedb6

### パッケージの追加
プロジェクトに以下を追加します。

```.cmd
npm i firebase firebase-admin text-encoding
```
```.cmd
npm i -D @types/text-encoding
```

### 環境変数ファイルの追加
プロジェクトのroot直下に、以下を追加します

```.js:.env.local
FIREBASE_STORAGE_BUCKET="<storageBucket>"
FIREBASE_SECRET_PROJECT_ID="<project_id>"
FIREBASE_SECRET_CLIENT_EMAIL="<private_key_id>"
FIREBASE_SECRET_PRIVATE_KEY="<private_key>"
```
storageBucketは、Firebaseプロジェクトの`SDK の設定と構成`を参照してください。
project_id、private_key_id、private_keyは、Firebaseから取得した秘密鍵です。


### コードの追加・変更
コーディング部分は、長くなるので割愛します。成果物のGitHubリンクを参照してください。
追加・変更したファイルは以下です。

- firebase/nodeApp.ts（追加）
- firebase/nodeFunctions.ts（追加）
- lib/posts
- pages/index.ts
- pages/posts/[id].tsx

実装はこちらを参考にしました。

https://www.pnkts.net/node-js-gcs

ドキュメント

https://firebase.google.com/docs/storage/admin/start

https://googleapis.dev/nodejs/storage/latest/Bucket.html#getFiles

### Firebase Storage のディレクトリ構成
Firebase Storageに**posts**というフォルダを作成して、その中にブログ記事をいれるようにしました。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358498/c24f7594-85ad-169e-7a0a-c7f9756a2ef8.png)

### 動作確認
設定・実装ができたら、Firebase Storageにブログ記事を配置して、開発環境でブログサイトを実行します。
開発環境での実行では、リクエストごとに記事を取得します。（デプロイする場合は、SSGはビルド時に取得）

```
npm run dev
```

### Vercel に環境変数を設定する
本番環境で運用するために、`.env.local`の内容を**Vercelの環境変数**に設定する必要があります。

**Setting** > **Enviroment Variables**

![無題5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358498/89111e2d-5783-1bfd-9bc6-31cef398e7d6.png)

### デプロイ
Vercelにデプロイします。
GitHubと連携していれば（チュートリアル通りに作成していれば）、GitHubにプッシュ（マージ）した段階で自動的にリビルド・デプロイされます。

<!-- ======================================================= -->
# 成果物
<!-- ======================================================= -->

https://github.com/nemutas/nextjs-tutorial-blog

<!-- ======================================================= -->
# まとめ
<!-- ======================================================= -->
Next.js（SSG）の**getStaticPaths**や**getStaticProps**箇所で、Firebaseを扱う場合は、サーバーサイドの実装が必要だということが重要な気がします。（言われてみれば当たり前ですが... この罠にハマりました）

Next >

https://qiita.com/nemutas/items/2e97e69f637e912e7f9b