2026年1月13日 星期二

連接並操作 Firestore 的 4 個標準步驟

 

第一步:在 Firebase 控制台取得「金鑰」

在你可以寫程式之前,必須先告訴程式你要連接哪一個專案:

  1. 前往 Firebase Console

  2. 點擊「專案設定」(齒輪圖示)。

  3. 在「您的應用程式」區塊,點擊 </> (Web) 圖示並註冊一個名稱。

  4. 你會看到一段 firebaseConfig 程式碼,長得像這樣:

    JavaScript
    const firebaseConfig = {
      apiKey: "AIzaSy...",
      authDomain: "你的專案ID.firebaseapp.com",
      projectId: "你的專案ID",
      // ... 其他參數
    };

    請複製這段內容,等一下會用到。


第二步:安裝或引入 SDK

如果你是在本地開發(使用 VS Code),通常會用 npm 安裝:

Bash
npm install firebase

如果你只是想先開一個簡單的 HTML 檔案試試看,可以在 <script> 標籤中引入(見下方的完整範例)。


第三步:撰寫連接程式碼 (JavaScript)

這是最核心的部分。我們將程式碼拆解為:初始化寫入資料讀取資料

JavaScript
// 1. 引入必要的 Firebase 功能
import { initializeApp } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-app.js";
import { getFirestore, collection, addDoc, getDocs } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-firestore.js";

// 2. 貼上你在第一步複製的設定值
const firebaseConfig = {
  apiKey: "你的API金鑰",
  authDomain: "...",
  projectId: "...",
  // ...
};

// 3. 初始化 Firebase 與 Firestore
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

// --- 操作範例 ---

// 【寫入資料】:在 "users" 抽屜新增一個人
async function addUser() {
  try {
    const docRef = await addDoc(collection(db, "users"), {
      name: "王小明",
      age: 25,
      city: "台北"
    });
    console.log("資料寫入成功,ID 為: ", docRef.id);
  } catch (e) {
    console.error("錯誤發生: ", e);
  }
}

// 【讀取資料】:把 "users" 抽屜裡的人全部列出來
async function getUsers() {
  const querySnapshot = await getDocs(collection(db, "users"));
  querySnapshot.forEach((doc) => {
    console.log(`${doc.id} => `, doc.data());
  });
}

第四步:CRUD 常用語法速查表

當你連接成功後,會頻繁用到以下指令:

功能語法 (簡寫)說明
新增 (自動 ID)addDoc(collection(db, "名稱"), {資料})讓系統幫你決定文件 ID。
指定 ID 新增/覆蓋setDoc(doc(db, "名稱", "ID"), {資料})你自己決定 ID (例如用身分證字號)。
讀取單一文件getDoc(doc(db, "名稱", "ID"))只拿特定一張紙的內容。
更新部分內容updateDoc(doc(db, "名稱", "ID"), {年齡: 26})只改其中一個欄位,其餘不變。
刪除文件deleteDoc(doc(db, "名稱", "ID"))把那份文件刪掉。

重要安全提醒:解決「權限拒絕」問題

剛開始寫程式時,你可能會遇到 FirebaseError: Missing or insufficient permissions。這是因為你的資料庫目前處於保護模式

測試時的解決方法:

  1. 回到 Firebase Console -> Firestore Database。

  2. 點擊上方標籤 "Rules" (規則)

  3. 把內容暫時修改成允許任何人讀寫(注意:僅限練習,正式上線不可這樣做):

    JavaScript
    service cloud.firestore {
      match /databases/{database}/documents {
        match /{document=**} {
          allow read, write: if true; 
        }
      }
    }
  4. 點擊「發佈」。

完整email認證範例.
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Firebase Email 登入範例</title>
    <style>
        body { font-family: sans-serif; padding: 20px; line-height: 1.6; background-color: #f9f9f9; }
        .card { border: 1px solid #ccc; padding: 20px; border-radius: 8px; max-width: 400px; background: white; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
        .status { color: blue; font-weight: bold; margin-bottom: 10px; }
        input { display: block; margin: 10px 0; padding: 10px; width: 100%; box-sizing: border-box; border: 1px solid #ddd; border-radius: 4px; }
        button { cursor: pointer; padding: 10px 15px; background: #007bff; color: white; border: none; border-radius: 4px; width: 100%; margin-top: 5px; }
        button:hover { background: #0056b3; }
        .secondary-btn { background: #28a745; } /* 綠色按鈕用於註冊 */
        .secondary-btn:hover { background: #218838; }
        .logout-btn { background: #dc3545; } /* 紅色按鈕用於登出 */
        .data-display { background: #eee; padding: 10px; margin-top: 10px; border-radius: 4px; font-size: 0.9em; }
        hr { margin: 20px 0; border: 0; border-top: 1px solid #eee; }
    </style>
</head>
<body>

    <h2>Firebase 使用者系統 (Email/Pass)</h2>

    <div class="card">
        <div id="auth-status" class="status">正在檢查狀態...</div>

        <!-- 登入與註冊區塊 (未登入時顯示) -->
        <div id="auth-form">
            <input type="email" id="email-input" placeholder="電子郵件">
            <input type="password" id="password-input" placeholder="密碼 (至少 6 位數)">
            <button id="btn-login">登入</button>
            <button id="btn-signup" class="secondary-btn">註冊新帳號</button>
        </div>

        <!-- 使用者功能區塊 (登入後顯示) -->
        <div id="app-content" style="display:none;">
            <p>歡迎,<span id="user-email" style="color:blue;"></span></p>
            <p>UID: <small id="user-uid"></small></p>
            
            <hr>
            <label>更新個人暱稱:</label>
            <input type="text" id="nickname-input" placeholder="輸入你想叫什麼">
            <button id="btn-save">儲存到 Firestore</button>
            <button id="btn-read">讀取我的資料</button>

            <div class="data-display" id="display-area">尚未讀取資料...</div>
            <hr>
            <button id="btn-logout" class="logout-btn">登出系統</button>
        </div>
    </div>

    <script type="module">
        import { initializeApp } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-app.js";
        // 引入 Email 登入所需的函式
        import { 
            getAuth, 
            createUserWithEmailAndPassword, 
            signInWithEmailAndPassword, 
            onAuthStateChanged, 
            signOut 
        } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-auth.js";
        import { getFirestore, doc, setDoc, getDoc } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-firestore.js";

        // 1. Firebase 設定值 (請替換成你的!)
        const firebaseConfig = {
            apiKey: "你的API金鑰",
            authDomain: "你的專案ID.firebaseapp.com",
            projectId: "你的專案ID",
            storageBucket: "...",
            messagingSenderId: "...",
            appId: "..."
        };

        const app = initializeApp(firebaseConfig);
        const auth = getAuth(app);
        const db = getFirestore(app);

        // --- DOM 元素 ---
        const authStatus = document.getElementById('auth-status');
        const authForm = document.getElementById('auth-form');
        const appContent = document.getElementById('app-content');
        const userEmailDisp = document.getElementById('user-email');
        const userUidDisp = document.getElementById('user-uid');
        const emailInput = document.getElementById('email-input');
        const passwordInput = document.getElementById('password-input');
        const nicknameInput = document.getElementById('nickname-input');
        const displayArea = document.getElementById('display-area');

        // --- 狀態監聽 ---
        onAuthStateChanged(auth, (user) => {
            if (user) {
                authStatus.innerText = "狀態:已登入";
                userEmailDisp.innerText = user.email;
                userUidDisp.innerText = user.uid;
                authForm.style.display = "none";
                appContent.style.display = "block";
            } else {
                authStatus.innerText = "狀態:請登入";
                authForm.style.display = "block";
                appContent.style.display = "none";
            }
        });

        // --- 功能:註冊 ---
        document.getElementById('btn-signup').onclick = async () => {
            const email = emailInput.value;
            const password = passwordInput.value;
            try {
                const userCredential = await createUserWithEmailAndPassword(auth, email, password);
                alert("註冊成功!歡迎 " + userCredential.user.email);
            } catch (e) {
                alert("註冊失敗: " + e.message);
            }
        };

        // --- 功能:登入 ---
        document.getElementById('btn-login').onclick = async () => {
            const email = emailInput.value;
            const password = passwordInput.value;
            try {
                await signInWithEmailAndPassword(auth, email, password);
                alert("登入成功!");
            } catch (e) {
                alert("登入失敗: " + e.message);
            }
        };

        // --- 功能:登出 ---
        document.getElementById('btn-logout').onclick = () => signOut(auth);

        // --- 功能:儲存資料 (Firestore) ---
        document.getElementById('btn-save').onclick = async () => {
            const user = auth.currentUser;
            const name = nicknameInput.value;
            try {
                await setDoc(doc(db, "users", user.uid), {
                    nickname: name,
                    email: user.email,
                    lastSeen: new Date()
                }, { merge: true }); // merge: true 表示只更新填寫的欄位,不覆蓋整份文件
                alert("存檔完成");
            } catch (e) {
                alert("存檔失敗:" + e.message);
            }
        };

        // --- 功能:讀取資料 (Firestore) ---
        document.getElementById('btn-read').onclick = async () => {
            const user = auth.currentUser;
            try {
                const docSnap = await getDoc(doc(db, "users", user.uid));
                if (docSnap.exists()) {
                    const data = docSnap.data();
                    displayArea.innerHTML = `暱稱: ${data.nickname}<br>帳號: ${data.email}`;
                } else {
                    displayArea.innerText = "尚未建立個人檔案資料。";
                }
            } catch (e) {
                alert("讀取失敗");
            }
        };
    </script>
</body>
</html>

沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。

連接並操作 Firestore 的 4 個標準步驟

  第一步:在 Firebase 控制台取得「金鑰」 在你可以寫程式之前,必須先告訴程式你要連接哪一個專案: 前往  Firebase Console 。 點擊「專案設定」(齒輪圖示)。 在「您的應用程式」區塊,點擊  </>  (Web) 圖示並註冊一個名稱。 你會...