貧者のアークテクチャ:Next.js on Cloudflare Pages&WorkersのAPI側でFirestoreを使えるようにした
こんにちは、@nabettuです。
個人開発の醍醐味といえばいかに安いインフラコストでサービスを作るか、というのがありますね!(諸説あります)
私は基本的にWebであればNext.jsと、Firebaseを利用することで認証、DB、ストレージを使ったサービスを基本無料で運用できる恩恵を受けています。ただそれもアクセスが増えるとどうしてもお金がかかるようになってしまいます。
フリーサービスならVercelが最も楽にデプロイ出来て良いのですが、商用サービスの場合は基本$20かかることや、商用プランにしてもアクセスが増えると結構高いため、最近Next.jsのホスティングにおいて、Vercelの代替手段を模索する動きが活発化しています。
一つの方法としてSPAで静的サイト化すると今度は個別のOGP画像が設定できないことや、APIをどうする問題なども出てしまいます。代替手段の一つとしてFirebase App HostingおよびCloud Runを利用するというのがありますが、これもまたアクセス数の増加に伴い料金が上昇してしまい、貧乏人には厳しいです。(あと個人的にCloudRunはDocker利用のためデプロイに時間がかかるのがマイナス)
そこでかなりの割合を無料で運用できるため、Cloudflare PagesやWorkersを利用してNext.jsをホスティングする方法が注目されています。しかし、これらのEdge環境ではFirebase Admin SDKが利用できないという課題があります。困ったね。
逆にこれが解決すると基本料金のかからないオールインワンのFirebaseのAuthやFirestoreを利用しつつ、ネックであるホスティング料金もどうにかできるはずです。ということで今回はその方法を解決するための手段を考えてきました。
Edge環境でのFirebase Authenticationの課題
Firebase Authenticationは、ユーザー認証を簡単に実装できる強力なツールです。
しかし、公式のFirebase Admin SDKはNode.jsの内部ライブラリ等に依存しており、これはEdge環境(Cloudflare WorkersやVercel Edge Functionsなど)では利用できません。そのため、EdgeでFirebase Authenticationを使用する際には、代替手段が必要となります。
Edge対応の認証ライブラリ next-firebase-auth-edge
Edge環境でFirebase Authenticationを利用するためのライブラリとして、next-firebase-auth-edgeがあります。このライブラリは、Web Crypto APIを使用してカスタムIDトークンの作成と検証を行い、EdgeでのFirebase Authenticationの利用ができるようになります。
特徴
- 最新のNext.js機能との互換性: App RouterやServer Componentsなど、最新のNext.jsの機能と互換性があります。
- ゼロバンドルサイズ: クライアントバンドルに追加のJavaScriptコードを導入せず、サーバーサイドで全ての処理を行います。
- 最小限の設定: 独自のAPIルートを作成したり、next.config.jsを変更する必要がありません。全ての処理はミドルウェアによって管理されます。
- セキュリティ: JWTの検証にはjoseを使用し、ユーザーのクッキーは回転キーで署名され、暗号解析攻撃を防ぎます。
詳細な設定方法や使用例については、公式ドキュメントを参照してください。
Edge環境でのFirestoreの利用
Firebase Authenticationに関しては上述のライブラリが存在しますが、Firestoreに関しては適切なライブラリが存在しなかったため、新たにfirebase-rest-firestoreを開発しました。このライブラリは、Edge環境でFirestoreを利用するためのREST APIクライアントであり、以下の特徴を持っています。
- Edgeランタイム環境での動作: Firebase Admin SDKが利用できない環境でもFirestoreを操作可能です。
- CRUD操作の完全サポート: ドキュメントの作成、読み取り、更新、削除といった基本操作をサポートしています。
- TypeScriptサポート: 型定義が提供されており、TypeScriptでの開発が容易です。
- トークンキャッシングによるパフォーマンス向上: 認証トークンのキャッシング機能により、パフォーマンスが向上します。
- シンプルで直感的なAPI: 基本的には本家のFirebase Admin SDKと同じインターフェースで利用できます。
使い方
以下に、firebase-rest-firestoreの基本的な使用例を示します。
import { createFirestoreClient } from "firebase-rest-firestore";
// クライアントの作成
const firestore = createFirestoreClient({
projectId: "your-project-id",
privateKey: "your-private-key",
clientEmail: "your-client-email",
});
// ドキュメントの作成
const gameRef = firestore.collection("games").doc("test");
await gameRef.set({
name: "The Legend of Zelda",
genre: "Action-adventure",
releaseYear: 1986,
});
// ドキュメントの読み取り
const doc = await gameRef.get();
console.log(doc.data());
// ドキュメントの更新
await gameRef.update({
releaseYear: 1987,
});
まとめ
Edge環境でのFirebaseサービスの利用には、公式SDKが対応していません。しかし、next-firebase-auth-edgeやfirebase-rest-firestoreのようなライブラリを活用することで、認証やデータベース操作を実現可能です。
- Cloudflare
- Firebase
- React(Next.js,特にReact Native)
これが貧者の3種の神器です。これらを使ってコストをかけずに最小工数でバンバンサービス作って行きましょう!
Discussion
個人開発に Cloudflare Workers と Firebase は本当に便利で安くて良いですよね。
Firestore をエッジで利用するために REST API をラップするのは誰もが通る道感があって、とても共感しながら記事を読ませていただきました。
私は Firestore を Cloudflare Workers を利用するために自作のラッパかfireworkersを利用していましたが、次に開発する際は firebase-rest-firestore を利用して、何かあればフィードバックしますね!ありがとうございます!