Skip to main content

Firebase功能:Authentication

步驟一:使用 Firebase 控制台設定 Google 身份驗證

既然你在 Firebase 控制台中啟用了 Authentication,這裡我會詳細說明如何在 Firebase 中設定 Google 身份驗證,並取得必要的憑證(Client ID)來與 Vite + React 專案整合。

2.1 前往 Firebase 控制台

  1. 開啟瀏覽器,前往 Firebase 控制台

  2. 如果你還沒有 Firebase 專案:

    • 點擊「新增專案」,輸入專案名稱(例如 ReactGoogleAuth),然後點擊「繼續」。

    • 選擇是否啟用 Google Analytics(可選,建議先關閉以簡化流程),然後點擊「建立專案」。

    • 等待專案建立完成,點擊「繼續」進入專案主頁。

  3. 如果你已經有專案,點擊專案名稱進入 Firebase 控制台。

2.2 啟用 Authentication 並設定 Google 登入

  1. 在 Firebase 控制台的左側選單,點擊「建構」 > 「Authentication」。

  2. 點擊「開始使用」按鈕,進入 Authentication 設定頁面。

  3. 在「登入方法」標籤中,找到「Google」並點擊它。

  4. 啟用 Google 登入:

    • 點擊「Google」旁邊的編輯圖示(鉛筆圖案)。

    • 將「啟用」開關切到開啟狀態。

    • 在「網頁 SDK 配置」中,選擇你的專案公開名稱(通常會自動填入你的 Firebase 專案名稱)。

    • 輸入支援的電子郵件地址(用於接收 Firebase 的通知)。

    • 點擊「儲存」。

2.3 取得 Google OAuth Client ID

  1. 啟用 Google 登入後,Firebase 會自動在背後的 Google Cloud Console 中建立一個 OAuth 2.0 用戶端 ID。你可以在 Firebase 控制台中找到這個 Client ID:

    • 在「Authentication」 > 「登入方法」 > 「Google」區塊中,點擊「網頁 SDK 配置」展開。

    • 你會看到一個「Web Client ID」(例如 1234567890-abc123def456.apps.googleusercontent.com),複製這個 ID,稍後會用在環境變數中。

  2. 設定已授權的 JavaScript 來源

    • Firebase 會自動將你的 Firebase 專案的網域(例如 your-project-id.firebaseapp.com)加入 Google Cloud Console 的「已授權的 JavaScript 來源」。但由於你在本地開發,需額外加入 http://localhost:5173

    • 將外部專案的用戶端 ID 新增至許可清單 (選用)

      沿用現有 Google 專案的用戶端 ID。在 ++Google API 控制台++選取專案,即可查看現有專案的用戶端 ID

    • 前往 Google Cloud Console,點擊左上角的下拉選單,選擇與 Firebase 專案對應的 Google Cloud 專案(名稱通常與 Firebase 專案相同或類似)。

    • 在左側選單中,點擊「API 與服務」 > 「憑證」。

    • 找到名為「Web client (auto created by Google Service)」的 OAuth 2.0 用戶端 ID,點擊編輯。

    • 在「已授權的 JavaScript 來源」中,新增:

      http://localhost
      http://localhost:5173
    • 點擊「儲存」。

2.4 設定 Firebase 應用程式

為了讓你的 React 應用程式能與 Firebase 互動,你需要將 Firebase 的配置資訊加入專案:

  1. 在 Firebase 控制台的專案主頁,點擊左側選單中的「專案總覽」 > 「專案設定」。

  2. 在「您的應用程式」區塊,點擊「網頁應用程式」圖示(</>),然後輸入應用程式名稱(例如 React App),點擊「註冊應用程式」。

  3. Firebase 會提供一組 JavaScript 配置程式碼,包含 apiKey、authDomain 等資訊。複製這段配置,稍後會用在你的 React 專案中。


步驟二:安裝 Firebase 並修改程式碼

由於你使用的是 Firebase Authentication,我們需要安裝 Firebase SDK,並使用 Firebase 的 Google 身份驗證功能來取代 @react-oauth/google。以下是調整後的步驟:

3.1 安裝 Firebase SDK

  1. 在終端機中,進入你的 Vite + React 專案目錄,執行以下指令:

    npm install firebase
  2. 確認 package.json 中有以下依賴:

    "dependencies": {
    "firebase": "^10.12.2",
    // 其他依賴...
    }

3.2 初始化 Firebase

  1. 在 src 資料夾中建立一個新檔案 firebase.js,用於初始化 Firebase:

    import { initializeApp } from 'firebase/app';
    import { getAuth, GoogleAuthProvider } from 'firebase/auth';

    // Firebase 配置,從 Firebase 控制台複製
    const firebaseConfig = {
    apiKey: '你的-api-key',
    authDomain: '你的專案-id.firebaseapp.com',
    projectId: '你的專案-id',
    storageBucket: '你的專案-id.appspot.com',
    messagingSenderId: '你的-messaging-sender-id',
    appId: '你的-app-id',
    };

    // 初始化 Firebase
    const app = initializeApp(firebaseConfig);
    const auth = getAuth(app);
    const googleProvider = new GoogleAuthProvider();

    export { auth, googleProvider };
    • 將 firebaseConfig 中的值替換為你在 Firebase 控制台「專案設定」中取得的配置資訊。

3.3 修改 src/App.jsx

以下是使用 Firebase Authentication 實現 Google 登入的完整程式碼:

import { useState, useEffect } from 'react';
import { auth, googleProvider } from './firebase';
import { signInWithPopup, signOut } from 'firebase/auth';
import './App.css';

function App() {
const [user, setUser] = useState(null);

// 監聽 Firebase Authentication 的狀態
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((currentUser) => {
if (currentUser) {
setUser({
name: currentUser.displayName,
email: currentUser.email,
});
} else {
setUser(null);
}
});
return () => unsubscribe();
}, []);

// 處理 Google 登入
const handleGoogleLogin = async () => {
try {
const result = await signInWithPopup(auth, googleProvider);
const user = result.user;
setUser({
name: user.displayName,
email: user.email,
});
console.log('登入成功:', user);
} catch (error) {
console.error('登入失敗:', error.message);
}
};

// 處理登出
const handleLogout = async () => {
try {
await signOut(auth);
setUser(null);
console.log('已登出');
} catch (error) {
console.error('登出失敗:', error.message);
}
};

return (
<div className="App">
<h1>React + Vite + Firebase Google 身份驗證</h1>
{user ? (
<div>
<h2>歡迎,{user.name}</h2>
<p>電子郵件:{user.email}</p>
<button onClick={handleLogout}>登出</button>
</div>
) : (
<button onClick={handleGoogleLogin}>使用 Google 登入</button>
)}
</div>
);
}

export default App;

程式碼說明

  • useEffect:監聽 Firebase Authentication 的狀態變化,當使用者登入或登出時更新 user 狀態。

  • signInWithPopup:觸發 Google 登入彈窗,成功後取得使用者資訊。

  • signOut:執行 Firebase 的登出功能。

  • 這裡使用 Firebase 的 GoogleAuthProvider,取代原本的 @react-oauth/google,因為 Firebase 提供了更簡單的 API 來處理 Google 身份驗證。

3.4 修改環境變數(可選)

如果你需要將 Firebase 配置儲存在環境變數中,可以在 .env 檔案中加入:

VITE_FIREBASE_API_KEY=你的-api-key
VITE_FIREBASE_AUTH_DOMAIN=你的專案-id.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=你的專案-id
VITE_FIREBASE_STORAGE_BUCKET=你的專案-id.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=你的-messaging-sender-id
VITE_FIREBASE_APP_ID=你的-app-id

然後修改 firebase.js:

import { initializeApp } from 'firebase/app';
import { getAuth, GoogleAuthProvider } from 'firebase/auth';

const firebaseConfig = {
apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET,
messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
appId: import.meta.env.VITE_FIREBASE_APP_ID,
};

const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const googleProvider = new GoogleAuthProvider();

export { auth, googleProvider };

步驟三:測試應用程式

  1. 確保 firebase.js 中的配置正確。

  2. 執行以下指令啟動開發伺服器:

    npm run dev
  3. 開啟瀏覽器,訪問 http://localhost:5173

  4. 點擊「使用 Google 登入」按鈕,應該會彈出 Google 登入視窗。

  5. 成功登入後,頁面會顯示使用者的名稱和電子郵件,並提供登出按鈕。


常見問題與解決方法

  1. 錯誤:auth/unauthorized-domain

  2. Firebase 配置無效

    • 檢查 firebase.js 中的配置是否與 Firebase 控制台中的值一致。

    • 如果使用環境變數,確保 .env 檔案正確,且變數名稱以 VITE_ 開頭。

  3. 登入彈窗未出現

    • 檢查瀏覽器控制台是否有錯誤訊息。

    • 確保 Firebase 的 Google 登入方法已在 Authentication 頁面啟用。


進階功能(可選)

  1. 保護路由 如果你使用 react-router-dom,可以使用以下方式保護路由:

    import { Navigate } from 'react-router-dom';
    import { auth } from './firebase';
    import { useAuthState } from 'react-firebase-hooks/auth';

    function ProtectedRoute({ children }) {
    const [user, loading] = useAuthState(auth);
    if (loading) return <div>載入中...</div>;
    return user ? children : <Navigate to="/login" />;
    }
    • 需要安裝 react-firebase-hooks:

      npm install react-firebase-hooks
  2. 自動登出 Firebase 的 onAuthStateChanged 會自動處理 token 過期,但你可以監聽 token 的更新:

    import { getIdTokenResult } from 'firebase/auth';

    const checkTokenExpiration = async (user) => {
    const tokenResult = await getIdTokenResult(user);
    const expiresIn = tokenResult.expirationTime - Date.now();
    setTimeout(() => {
    signOut(auth);
    console.log('Token 已過期,自動登出');
    }, expiresIn);
    };