開発効率化

Firebase Studio終了前の移行入門——Next.js開発環境をローカルとCIへ戻す

Firebase Studioの新規ワークスペース作成停止を受け、Next.js + Firestoreのプロジェクトをローカル開発、Emulator Suite、GitHub Actions、App Hostingへ移行する実践手順を解説します。

2026年6月20日
FirebaseNext.jsFirestoreGitHub Actions移行
Firebase Studio終了前の移行入門——Next.js開発環境をローカルとCIへ戻す

はじめに

Firebase Studioを使ってプロトタイプを作っていて、こんな状況はありませんか?

  • ブラウザ上では動くが、ローカルで同じ開発環境を再現できていない
  • FirestoreやAuthenticationの設定がFirebase Studio内の作業に寄っている
  • GitHub Actionsでビルド、テスト、デプロイの入口を固定できていない
  • 2026年6月22日以降も新しいワークスペースを作れる前提で運用している

Firebase公式ドキュメントでは、Firebase Studioは段階的に終了すると案内されています。2026年6月22日に新規ワークスペース作成が無効化され、2027年3月22日にFirebase Studio自体が終了し、残ったデータは削除されます。一方で、Cloud Firestore、Authentication、App HostingなどのFirebaseサービスは影響を受けない、と明記されています。

本記事では、架空の経理SaaS「KaikeiBoard」を題材に、Firebase Studio上のNext.js + Firestoreプロジェクトを、ローカル開発、Firebase Emulator Suite、GitHub Actions、Firebase App Hostingへ移す手順を整理します。読み終えると、ブラウザIDE依存ではなく、チームで再現できる開発基盤へ移行する流れがつかめます。

何が変わるのか

Firebase Studio終了のポイントは、「Firebaseのバックエンドが止まる」ことではありません。終了するのは開発環境としてのFirebase Studioです。既存のFirestoreデータ、Authenticationユーザー、App Hostingなどのサービスは引き続き動きます。

ただし、開発フローは見直しが必要です。特に業務アプリでは、ワークスペースに閉じた設定や手作業のデプロイを残したままにすると、引き継ぎや障害対応で困ります。

移行の考え方を表にすると、次のようになります。

移行対象移行後の置き場所確認すること
アプリコードGitHub repositorypackage.json、環境変数、ビルド手順
Firestoreルールリポジトリ内のrulesファイル本番ルールとローカルファイルの差分
Firestore indexesfirestore.indexes.jsonクエリ追加時にCIで検知できるか
ローカル検証Firebase Emulator Suite本番データへ触らず試せるか
デプロイApp Hosting / GitHub Actions誰が、どのブランチから反映するか

事前準備

KaikeiBoardは、請求書、入金予定、承認ログをFirestoreに保存するNext.js App Routerアプリという想定です。まずは、開発に必要な道具をリポジトリへ明示します。

yarn add firebase firebase-admin
yarn add -D firebase-tools vitest @firebase/rules-unit-testing

Firebase公式ドキュメントでは、Firebase JavaScript SDKはfirebaseパッケージ、Admin SDK for Node.jsはfirebase-adminパッケージとして案内されています。Firebase CLIはfirebase-toolsで提供されています。Security Rulesのユニットテストでは、公式ドキュメントが@firebase/rules-unit-testingを案内しています。

次に、Firebaseプロジェクト設定を初期化します。

firebase --version
firebase init
firebase init emulators
firebase init apphosting

firebase init emulatorsは、利用するエミュレータを選び、ポートや設定をfirebase.jsonへ書き込みます。公式ドキュメント上、Emulator SuiteにはNode.js 16以上とJava JDK 11以上が必要です。App Hosting側はfirebase init apphostingapphosting.yamlを作成できます。

ハンズオン1: Firebase依存をコードに閉じ込める

最初にやるべきことは、Firebase Studio内の暗黙設定に頼らず、アプリから見えるFirebase初期化をコード化することです。Next.jsでは、クライアントSDKとAdmin SDKを混ぜないように分けます。

// src/lib/firebase/client.ts
import { getApps, initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";

const firebaseConfig = {
  apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
  authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
  projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
};

export const firebaseApp =
  getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0];

export const db = getFirestore(firebaseApp);

サーバー側で管理者権限が必要な処理は、firebase-adminへ寄せます。Firestoreの監査ログを書き込むような処理は、Server ActionやRoute Handlerから呼ぶ形にします。

// src/lib/firebase/admin.ts
import { getApps, initializeApp } from "firebase-admin/app";
import { getFirestore } from "firebase-admin/firestore";

if (getApps().length === 0) {
  initializeApp();
}

export const adminDb = getFirestore();

例えば、請求書承認時に監査ログを残す処理は次のように書けます。

// src/app/invoices/[invoiceId]/actions.ts
"use server";

import { FieldValue } from "firebase-admin/firestore";
import { adminDb } from "@/lib/firebase/admin";

export async function approveInvoice(invoiceId: string, reviewerId: string) {
  if (!invoiceId || !reviewerId) {
    throw new Error("invoiceId and reviewerId are required");
  }

  await adminDb.collection("auditLogs").add({
    action: "invoice.approve",
    invoiceId,
    reviewerId,
    createdAt: FieldValue.serverTimestamp(),
  });

  await adminDb.collection("invoices").doc(invoiceId).update({
    status: "approved",
    approvedAt: FieldValue.serverTimestamp(),
  });
}

ここで重要なのは、Firebase Studioでたまたま動いていた処理を、そのまま画面コンポーネントに散らさないことです。SDK初期化、Admin権限、業務処理を分けると、ローカル検証とCIの対象が明確になります。

ハンズオン2: Firestore Emulatorで本番データに触らない

移行直後は、本番Firestoreを使って手元確認したくなります。しかし、経理や承認ログを扱うアプリでは危険です。まずEmulator Suiteへ逃がします。

package.jsonには、Firebase CLIを呼ぶスクリプトを置きます。

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "test": "vitest run",
    "firebase": "firebase",
    "emulators": "firebase emulators:start --only firestore,auth",
    "emulators:test": "firebase emulators:exec --only firestore,auth \"yarn test\""
  }
}

Firestore Emulatorへ接続するクライアント初期化も、開発時だけに限定します。

// src/lib/firebase/client.ts
import { connectFirestoreEmulator, getFirestore } from "firebase/firestore";

export const db = getFirestore(firebaseApp);

if (process.env.NEXT_PUBLIC_USE_FIREBASE_EMULATOR === "true") {
  connectFirestoreEmulator(db, "127.0.0.1", 8080);
}

エミュレータ利用時の環境変数は、.env.localに分けます。

NEXT_PUBLIC_USE_FIREBASE_EMULATOR=true
NEXT_PUBLIC_FIREBASE_PROJECT_ID=kaikeiboard-dev

公式ドキュメントでは、Firestore Emulatorの標準ポートは8080、Emulator Suite UIは4000です。ポートを変えた場合は、firebase.jsonとアプリ側の接続先を必ず合わせます。

ハンズオン3: GitHub Actionsで移行後の入口を固定する

Firebase Studioを離れるなら、「誰の環境では動いた」を卒業する必要があります。最低限、PRでyarn buildが通ることをGitHub Actionsで固定します。

name: Web CI

on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "yarn"

      - run: yarn install --frozen-lockfile
      - run: yarn build

Firestoreルールやエミュレータテストを入れる場合は、別jobに分けると見通しがよくなります。

  firestore-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "yarn"

      - run: yarn install --frozen-lockfile
      - run: yarn emulators:test

この時点では、本番デプロイまで自動化しなくても構いません。まずは「PRで壊れていないこと」「mainに入ったコードが同じ手順でビルドできること」を固定します。

ハンズオン4: App Hosting設定をリポジトリに置く

Next.jsをFirebaseで動かす場合、Firebase App HostingはNext.jsを組み込みサポートしています。公式ドキュメントでは、GitHub連携、Cloud Build、Cloud Run、Cloud CDN、Cloud Secret Managerとの統合が説明されています。

apphosting.yamlには、Cloud Runのリソースや環境変数を記述できます。最初から大きくしすぎず、KaikeiBoardでは小さく始めます。

# apphosting.yaml
runConfig:
  minInstances: 0
  maxInstances: 5
  concurrency: 80
  cpu: 1
  memoryMiB: 512

env:
  - variable: NEXT_PUBLIC_FIREBASE_PROJECT_ID
    value: kaikeiboard-prod
    availability:
      - BUILD
      - RUNTIME

App Hosting backendは、Firebase CLIでも作成できます。

firebase apphosting:backends:create --project PROJECT_ID

公式ドキュメントでは、このコマンドはFirebase CLI v13.15.4以降で使えると案内されています。実行時にはリージョン、GitHub接続、アプリのルートディレクトリ、ライブブランチなどをプロンプトで選びます。

移行チェックリスト

Firebase Studioの終了日はまだ先でも、2026年6月22日に新規ワークスペース作成が止まるため、移行計画は早めに切るべきです。

優先度作業完了条件
GitHubにコードを集約ローカルでyarn buildが通る
Firebase初期化をコード化Studio外でもFirestoreへ接続できる
Emulator Suiteを設定本番データなしで主要フローを試せる
GitHub Actionsを追加PRごとにビルドが走る
apphosting.yamlを追加App Hostingの設定がレビュー可能になる
環境変数を棚卸し公開変数と秘密情報が分離されている
デプロイ権限を整理main反映と本番反映の責任者が明確

参考リンク

まとめ

Firebase Studioの終了は、Firebaseを使った開発をやめる話ではありません。むしろ、プロトタイプをチーム開発に耐える形へ移すタイミングです。

Next.js + Firestoreのプロジェクトでは、まずコードをGitHubへ寄せ、Firebase初期化を明示し、Emulator Suiteで本番データから切り離し、GitHub Actionsでビルドの入口を固定します。そのうえで、App HostingやHostingのデプロイ設定をリポジトリに置けば、Firebase Studioに依存しない開発基盤へ移行できます。