完整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>
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。