開始使用網頁專用 Crashlytics

選取平台: iOS+ Android Android NDK Web Flutter Unity


本指南說明如何在網頁應用程式中開始使用 Firebase Crashlytics。

在應用程式中設定 Firebase Crashlytics SDK 後,您可以在 Firebase 控制台中取得完整的當機報告。使用網頁應用程式的 Crashlytics,即可取得錯誤報告。

事前準備

設定 Crashlytics 時,您必須在 Firebase 控制台和 IDE 中執行多項工作,例如新增應用程式的 Firebase 設定和 Crashlytics SDK。如要完成設定,您必須強制測試當機,將第一份當機報告傳送至 Firebase。

如要在網頁應用程式中手動設定 Crashlytics,請務必完成下列必要條件:

  • 如果您還沒有 Firebase 專案和 Firebase 應用程式,請先建立。如果您尚未將 Firebase 新增至 JavaScript 專案,請先新增。

  • 確認您的帳戶具備專案的擁有者權限。必須具備這項權限,才能啟用必要的 API 和 IAM 角色。

  • 確認 Firebase 專案採用即付即用 Blaze 定價方案。Crashlytics 網頁版使用 Cloud Logging 儲存遙測資料,並使用 Cloud Storage 儲存來源對應,這些都是付費產品,但提供免付費方案。進一步瞭解 Logging 定價和 Cloud Storage 定價。

步驟 1:為網頁應用程式啟用 Crashlytics

網頁版 Crashlytics 會使用 Cloud Logging、Error Reporting 和 Cloud Storage,因此您必須啟用這些 API,並設定專案權限。您可以使用 Firebase 控制台或 Firebase CLI,為網頁應用程式啟用 Crashlytics。

使用 Firebase 控制台

  1. 在 Firebase 控制台中,依序前往「DevOps & Engagement」(開發運作與參與) >「Crashlytics dashboard」(Crashlytics 資訊主頁)。

  2. 從頁面頂端的下拉式選單中選取網頁應用程式。

  3. 按一下「設定 Crashlytics」,然後按照畫面上的指示操作。

使用 Firebase CLI

如果您偏好透過終端機設定專案,或使用 AI 程式設計代理,可以使用 Firebase CLI:

  1. 請確認您已安裝 Firebase CLI 15.35.0 以上版本,且已通過驗證 (firebase login)。瞭解如何安裝或更新 Firebase CLI。

  2. 執行下列指令,為網頁應用程式設定 Crashlytics:

    firebase crashlytics:setup \
      --app FIREBASE_APP_ID \
      --project PROJECT_ID
    

    這個指令會執行下列設定步驟:

    • 確認專案採用即付即用 Blaze 定價方案,並在必要時提示您升級。

    • 啟用必要的 Crashlytics 和遙測 API (firebasetelemetry.googleapis.com、firebasetelemetryadmin.googleapis.com、firebasecrashlytics.googleapis.com 和 clienttelemetry.googleapis.com)。

    • 如果網頁應用程式的 API 金鑰設有 API 限制,請將 clienttelemetry.googleapis.com 新增至允許的 API。

    • 設定網頁應用程式的 Crashlytics 遙測設定。

    • 以互動方式執行時,系統會提示您選擇是否啟用新問題和迴歸問題的電子郵件快訊。

步驟 2:在應用程式中新增及初始化 SDK

  1. 安裝 Crashlytics SDK:

    npm install firebase
    
  2. 初始化 FirebaseApp 執行個體:

    建立中央設定公用程式檔案,以便使用單例模式初始化。如要查看 Firebase 應用程式設定值,請前往 Firebase 控制台的「Project settings」(專案設定) >「General」(一般) 頁面,然後前往「Your apps」(您的應用程式) 資訊卡,並選取網頁應用程式。

    // src/lib/firebase.ts
    import { initializeApp, getApps, getApp } from '@firebase/app';
    
    const firebaseConfig = {
      apiKey: "API_KEY",
      authDomain: "AUTH_DOMAIN",
      projectId: "PROJECT_ID",
      storageBucket: "STORAGE_BUCKET",
      messagingSenderId: "MESSAGING_SENDER_ID",
      appId: "FIREBASE_APP_ID"
    };
    
    // Guarantee singleton initialization across renders or module refreshes
    export const app = getApps().length === 0
      ? initializeApp(firebaseConfig)
      : getApp();
    

步驟 3:為框架設定自動擷取錯誤

自動架構錯誤接收器和手動追蹤器都會使用共用的 FirebaseApp 執行個體。選取架構,設定自動擷取錯誤:

Angular

在 src/app/app.config.ts 中,將 provideCrashlytics(() => app) 新增至應用程式的供應商,即可與 Angular 全域錯誤擷取執行階段和自動路徑追蹤功能整合:

// src/app/app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideCrashlytics } from '@firebase/crashlytics/angular';
import { app } from '../lib/firebase'; // Shared initialization script
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    provideCrashlytics(() => app)
  ]
};

Next.js

Next.js 15.3 以上版本 (建議):用戶端檢測 (instrumentation-client.ts)

Next.js 15.3 以上版本包含透過 instrumentation-client.ts (或 instrumentation-client.js) 執行的原生用戶端檢測。Next.js 會在 React 凍結開始前,在瀏覽器中執行這個檔案。

建立 src/instrumentation-client.ts (如果未使用 src/ 目錄,則在專案根目錄中建立 instrumentation-client.ts),並初始化 Crashlytics:

// src/instrumentation-client.ts
import { getCrashlytics } from '@firebase/crashlytics';
import { app } from './lib/firebase'; // Shared initialization script

getCrashlytics(app);

這個檔案會在 React 凍結前初始化 Crashlytics,並自動註冊全域錯誤事件監聽器 (error 和 unhandledrejection),完全不需修改 src/app/layout.tsx 或任何 React 元件。

Next.js < 15.3:用戶端 (App Router 版面配置)

如果是 15.3 之前的 Next.js 版本,layout.tsx 預設為伺服器元件。由於 FirebaseApp 無法序列化,請將 <FirebaseCrashlytics> (來自 @firebase/crashlytics/react,用於初始化 Crashlytics 並擷取未偵測到的錯誤) 包裝在標有 'use client' 指令的用戶端元件 (例如 src/components/CrashlyticsProvider.tsx) 中:

// src/components/CrashlyticsProvider.tsx
'use client';

import React from 'react';
import { FirebaseCrashlytics } from '@firebase/crashlytics/react';
import { app } from '../lib/firebase'; // Shared initialization script

export function CrashlyticsProvider({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <>
      <FirebaseCrashlytics firebaseApp={app} />
      {children}
    </>
  );
}

然後使用 <CrashlyticsProvider> 包裝根層級版面配置:

// src/app/layout.tsx
import React from 'react';
import { CrashlyticsProvider } from '../components/CrashlyticsProvider';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <CrashlyticsProvider>
          {children}
        </CrashlyticsProvider>
      </body>
    </html>
  );
}

React (不含 React Router)

使用 <FirebaseCrashlytics> 錯誤邊界元件包裝根應用程式元件 (通常是 src/App.tsx 或 src/main.tsx)。這個元件會做為全域接收器,處理瀏覽器和 React UI 中未處理的拒絕和例外狀況。它會包裝所有子元件階層,並自動擷取未偵測到的例外狀況或轉送錯誤:

// src/App.tsx
import React from 'react';
import { FirebaseCrashlytics } from '@firebase/crashlytics/react';
import { app } from './lib/firebase'; // Shared initialization script

export default function App({
  children,
}: {
  children?: React.ReactNode;
}) {
  return (
    <FirebaseCrashlytics firebaseApp={app}>
      {children}
    </FirebaseCrashlytics>
  );
}

React Router (v6+)

如果您使用的是 React Router v6 以上版本,請將 React Router 的 <Routes> 容器替換為 <CrashlyticsRoutes>。這項功能會自動對應各路徑的錯誤邊界,並使用範本路徑名稱 (例如 /profile/:userId) 追蹤錯誤:

// src/App.tsx
import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import { CrashlyticsRoutes } from '@firebase/crashlytics/react-router';
import { app } from './lib/firebase'; // Shared initialization script
import Home from './pages/Home';
import Profile from './pages/Profile';
import Product from './pages/Product';

export default function App() {
  return (
    <BrowserRouter>
      <CrashlyticsRoutes firebaseApp={app}>
        <Route path="/" element={<Home />} />
        <Route path="/profile/:userId" element={<Profile />} />
        <Route path="/product/:productId/details" element={<Product />} />
      </CrashlyticsRoutes>
    </BrowserRouter>
  );
}

TanStack Router

如果應用程式使用 TanStack Router,請使用 getCrashlytics(app) 初始化 Crashlytics,並直接在路由器執行個體設定 (defaultOnCatch) 中附加預設錯誤記錄:

import { recordError, getCrashlytics } from '@firebase/crashlytics';
import { app } from './lib/firebase'; // Shared initialization script

import { createRouter } from '@tanstack/react-router';
import { routeTree } from './routeTree.gen';

const crashlytics = getCrashlytics(app);

const router = createRouter({
  routeTree,
  defaultOnCatch: (error, errorInfo) => {
    recordError(crashlytics, error, errorInfo);
  },
});

(選用) 步驟 4:設定應用程式版本管理

強烈建議您在網頁應用程式建構作業中加入明確的版本字串,以便將迴歸問題隔離至特定部署作業。為架構初始化 Crashlytics SDK 時,請在 CrashlyticsOptions 中傳遞 appVersion (使用版本字串或建構階段環境變數,例如 process.env.NEXT_PUBLIC_APP_VERSION 或 import.meta.env.VITE_APP_VERSION):

Angular

將 CrashlyticsOptions 物件和 appVersion 做為第二個引數,傳遞至 src/app/app.config.ts 中的 provideCrashlytics:

// src/app/app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideCrashlytics } from '@firebase/crashlytics/angular';
import { app } from '../lib/firebase'; // Shared initialization script
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    provideCrashlytics(() => app, {
      appVersion: 'APP_VERSION'
    })
  ]
};

Next.js

Next.js 15.3 以上版本 (建議):用戶端檢測 (instrumentation-client.ts)

將 CrashlyticsOptions 物件和 appVersion 做為第二個引數,傳遞至 src/instrumentation-client.ts 中的 getCrashlytics:

// src/instrumentation-client.ts
import { getCrashlytics } from '@firebase/crashlytics';
import { app } from './lib/firebase'; // Shared initialization script

getCrashlytics(app, {
  appVersion: 'APP_VERSION'
});

Next.js < 15.3:用戶端 (App Router 版面配置)

在 src/components/CrashlyticsProvider.tsx 中,使用 appVersion 將 crashlyticsOptions 傳遞至 <FirebaseCrashlytics>:

// src/components/CrashlyticsProvider.tsx
'use client';

import React from 'react';
import { FirebaseCrashlytics } from '@firebase/crashlytics/react';
import { app } from '../lib/firebase'; // Shared initialization script

const crashlyticsOptions = {
  appVersion: 'APP_VERSION'
};

export function CrashlyticsProvider({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <>
      <FirebaseCrashlytics
        firebaseApp={app}
        crashlyticsOptions={crashlyticsOptions}
      />
      {children}
    </>
  );
}

React (不含 React Router)

在 src/App.tsx 中,使用 appVersion 將 crashlyticsOptions 傳遞至 <FirebaseCrashlytics>:

// src/App.tsx
import React from 'react';
import { FirebaseCrashlytics } from '@firebase/crashlytics/react';
import { app } from './lib/firebase'; // Shared initialization script

const crashlyticsOptions = {
  appVersion: 'APP_VERSION'
};

export default function App({
  children,
}: {
  children?: React.ReactNode;
}) {
  return (
    <FirebaseCrashlytics
      firebaseApp={app}
      crashlyticsOptions={crashlyticsOptions}
    >
      {children}
    </FirebaseCrashlytics>
  );
}

React Router (v6+)

在 src/App.tsx 中,使用 appVersion 將 crashlyticsOptions 傳遞至 <CrashlyticsRoutes>:

// src/App.tsx
import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import { CrashlyticsRoutes } from '@firebase/crashlytics/react-router';
import { app } from './lib/firebase'; // Shared initialization script
import Home from './pages/Home';
import Profile from './pages/Profile';
import Product from './pages/Product';

const crashlyticsOptions = {
  appVersion: 'APP_VERSION'
};

export default function App() {
  return (
    <BrowserRouter>
      <CrashlyticsRoutes
        firebaseApp={app}
        crashlyticsOptions={crashlyticsOptions}
      >
        <Route path="/" element={<Home />} />
        <Route path="/profile/:userId" element={<Profile />} />
        <Route path="/product/:productId/details" element={<Product />} />
      </CrashlyticsRoutes>
    </BrowserRouter>
  );
}

TanStack Router

將 CrashlyticsOptions 物件和 appVersion 做為第二個引數傳遞至 getCrashlytics:

import { recordError, getCrashlytics } from '@firebase/crashlytics';
import { app } from './lib/firebase'; // Shared initialization script

import { createRouter } from '@tanstack/react-router';
import { routeTree } from './routeTree.gen';

const crashlytics = getCrashlytics(app, {
  appVersion: 'APP_VERSION'
});

const router = createRouter({
  routeTree,
  defaultOnCatch: (error, errorInfo) => {
    recordError(crashlytics, error, errorInfo);
  },
});

步驟 5:強制測試當機

您需要強制測試當機,才能完成設定 Crashlytics,並在 Firebase 控制台的 Crashlytics 資訊主頁中看見初始資料。

  1. 在應用程式中加入程式碼,強制造成測試當機。

    在 React、Next.js 或 Angular 應用程式中,新增測試按鈕或路徑觸發條件,點選後會擲回執行階段錯誤:

    // Trigger an unhandled exception on button click or route load
    function handleTestCrash() {
      throw new Error("Crashlytics Web SDK Test Unhandled Error!");
    }
    

    如果您已使用 <FirebaseCrashlytics> (React 或 Next.js)、provideCrashlytics (Angular) 或 <CrashlyticsRoutes> (React Router) 設定自動擷取錯誤,擲回這項錯誤會自動擷取例外狀況,並排定上傳時間。

  2. 建構並執行應用程式,然後觸發測試錯誤,讓應用程式將第一份當機報告傳送至 Firebase。

  3. 在 Firebase 控制台中,依序前往 「DevOps & Engagement」>「Crashlytics dashboard」 ,查看測試當機報告:

    1. 從頁面頂端的下拉式選單中選取網頁應用程式。

    2. 重新整理頁面。測試例外狀況應該會在幾分鐘內顯示在「Issues」(問題) 表格中。

如果重新整理控制台後,五到十分鐘內仍未看到測試當機,請參閱「排解設定問題」。


Crashlytics 現在會監控網頁應用程式是否有錯誤。前往Crashlytics 資訊主頁,查看及調查所有報表和統計資料。

後續步驟

  • 取得可讀的當機報告:設定自動上傳來源對應 (.js.map),讓實際工作環境堆疊追蹤顯示原始檔案名稱和行號。
  • 自訂當機報告:瞭解如何回報已處理的例外狀況、新增自訂鍵、強制清除遙測記錄,以及設定取樣。