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


概要

本記事は、【JAMstack】Next.js × Firebase で JAMstack なブログサイトを作る①[概要]の続きとなっています。

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

ブログサイトの雛形の作成

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

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

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

Firebase プロジェクトの作成

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

※ リージョンの選択がある場合は、すべてasia-northeast1で統一します。

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

Storage からデータを取得する

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

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

パッケージの追加

プロジェクトに以下を追加します。

npm i firebase firebase-admin text-encoding
npm i -D @types/text-encoding

環境変数ファイルの追加

プロジェクトのroot直下に、以下を追加します

.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

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

ドキュメント

Firebase Storage のディレクトリ構成

Firebase Storageにpostsというフォルダを作成して、その中にブログ記事をいれるようにしました。

動作確認

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

npm run dev

Vercel に環境変数を設定する

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

Setting > Enviroment Variables

デプロイ

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

成果物

まとめ

Next.js(SSG)のgetStaticPathsgetStaticProps箇所で、Firebaseを扱う場合は、サーバーサイドの実装が必要だということが重要な気がします。(言われてみれば当たり前ですが... この罠にハマりました)

Next >