LoginSignup
27
23

More than 1 year has passed since last update.

Next.jsでFirestoreのデータをSSGする

Last updated at Posted at 2021-02-21

Firebaseを使ったアプリを作成する際、
Firestoreのデータをクライアント側でFetchすることが多かったのですが、

  • リアルタイムでの更新は不要
  • Firebase料金の見積もりを簡単にしたい(リクエスト量に応じて変動されたくない)

という要件での開発を求められそうだったので、
「これはSSGしかない!!」ということで勉強したことを備忘としてまとめます。

Next.js内でのFirebaseの初期化

【訂正: 2021/06/14】

初期化方法を訂正いたしました。
クライアント側で必要な初期化方法を掲載していましたが、
今回はSSGをするのでfirebase-adminでの初期化が必要でした。大変失礼いたしました。

詳しくはこちらで説明しています。
https://qiita.com/centerfield77/items/799f2840f48221c2f84d


初期化はfirebase-adminを使います。
firebase-admin は特権環境から Firebase を操作するため、自分で設定したFirestoreのルールに関係なくサーバー側から Firestore にアクセスできます。

firebase-admin を使用するにはまずプロジェクトの設定サービスアカウントから新しい秘密鍵の生成をクリックし、秘密鍵(json ファイル)をダウンロードします。

※このファイルが外部に漏れたら事故です。

スクリーンショット 2021-06-12 16.22.48.png

ダウンロードした json ファイルの中にproject_id, client_email, private_keyがあるので、それを.envに追加します。

.env
FIREBASE_PROJECT_ID="***************"
FIREBASE_CLIENT_EMAIL="***************"
FIREBASE_PRIVATE_KEY="***************"

初期化します。

/lib/db.js
import * as admin from 'firebase-admin';

if (!admin.apps.length) {
  admin.initializeApp({
    credential: admin.credential.cert({
      projectId: process.env.FIREBASE_PROJECT_ID,
      clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
      privateKey: process.env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n'),
    }),
  });
}

export const db = admin.firestore();

今回はfirestoreしか使わないのでfirestoreをdbとしてエクスポートしています。

getStaticProps()内でFirestoreのデータを取得する

Firestoreのデータはとてもシンプルなものを用意しました。
スクリーンショット 2021-02-21 18.30.29.png

これをgetStaticProps()内で取得しtasksという変数で返して、
それを上に書いてあるfunction Firebase()で受け取りレンダリングします。

/pages/Firebase.js
import { db } from '../lib/db';
import Link from 'next/link';

export default function Firebase({ tasks }) {
  return (
    <>
      <h1>Firebaseのページ</h1>
      <ul>
        {tasks.map((task) => (
          <li key={task.id}>{task.title}</li>
        ))}
      </ul>
      <Link href={`/`}>
        <a>戻る</a>
      </Link>
    </>
  );
}

export async function getStaticProps() {
  const tasks = [];
  const ref = await db.collection('tasks').get();
  ref.docs.map((doc) => {
    const data = { id: doc.id, title: doc.data().title };
    tasks.push(data);
  });
  return {
    props: {
      tasks,
    },
  };
}

ブラウザで確認

スクリーンショット 2021-02-21 18.39.37.png

問題なくFirestoreのデータが表示されてることを確認できました。

補足:Vercelでデプロイする場合

Vercel上でも環境変数の設定をする必要があります。

プロジェクトを選択 → SettingsEnvironment Variables
Plaintextにチェックを入れて一つずつ追加していきます。
スクリーンショット 2021-02-21 18.44.01.png

これでVercel上でビルドする際にもFirebaseの情報を取得できるようになります。
デプロイ後に本番環境でも問題なく閲覧できていることを確認できました。
スクリーンショット 2021-02-21 18.47.17.png

27
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
23