Firebase Authentication — Firebase
مصادقة Firebase
البريد وكلمة المرور
createUserWithEmailAndPassword(auth, email, password) و signInWithEmailAndPassword(...) (المثال الكامل). بعد التسجيل أرسل رابط التحقق: sendEmailVerification(user)، واستعادة كلمة المرور بـ sendPasswordResetEmail(auth, email).
الدخول بـ Google
signInWithPopup(auth, new GoogleAuthProvider()) على الحاسوب؛ وعلى الجوال أو المتصفحات التي تحظر النوافذ المنبثقة: signInWithRedirect. للتطبيقات الأصلية (React Native/Flutter) تُستخدم حزم المنصة.
حالة الدخول
import { onAuthStateChanged } from "firebase/auth";
import { auth } from "./firebase.js";
export function watchUser(cb) {
return onAuthStateChanged(auth, (user) => cb(user)); // null عند الخروج؛ يعيد دالة الإلغاء
}auth.currentUser قد يكون null لحظة تحميل الصفحة حتى تُستعاد الجلسة — اعتمد على onAuthStateChanged لا على قراءة فورية.
رسائل الأخطاء
أخطاء Firebase برموز مثل auth/invalid-credential و auth/email-already-in-use و auth/weak-password و auth/too-many-requests. حوّلها لرسائل عربية واضحة، ولا تكشف "البريد غير موجود" مقابل "كلمة المرور خاطئة" (Firebase الحديث يوحّدها إلى invalid-credential لهذا السبب).
الهوية على الخادم
إذا كان لديك خادم أو Cloud Function، لا تثق بـ uid يرسله العميل في الجسم. أرسل رمز المعرّف (await user.getIdToken()) في ترويسة Authorization، وتحقق منه على الخادم بـ Admin SDK:
// import { getAuth } from "firebase-admin/auth";
// const decoded = await getAuth().verifyIdToken(token); // يرمي إن كان مزوراً أو منتهياً
// const uid = decoded.uid;
const flow = ["user.getIdToken()", "Authorization: Bearer <token>", "admin.verifyIdToken(token)"];
console.log(flow.join(" ← "));الأدوار
للمشرفين استخدم Custom Claims (setCustomUserClaims(uid, { admin: true }) من Admin SDK)، فتظهر في الرمز وفي قواعد الأمان كـ request.auth.token.admin. لا تحفظ الدور في وثيقة يستطيع المستخدم تعديلها.
تمرين
أضف للمثال الكامل: إرسال رابط التحقق بعد التسجيل، ومنع الوصول لصفحة "حسابي" حتى يصبح user.emailVerified صحيحاً، وترجمة خمسة رموز أخطاء شائعة إلى رسائل عربية.
import {
getAuth,
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
signOut,
onAuthStateChanged,
GoogleAuthProvider,
signInWithPopup,
sendPasswordResetEmail
} from 'firebase/auth';
const auth = getAuth();
// ===== إنشاء حساب جديد =====
async function signUp(email, password) {
try {
const userCredential = await createUserWithEmailAndPassword(
auth, email, password
);
console.log('تم إنشاء الحساب:', userCredential.user.uid);
return userCredential.user;
} catch (error) {
console.error('خطأ:', error.message);
throw error;
}
}
// ===== تسجيل الدخول =====
async function signIn(email, password) {
try {
const userCredential = await signInWithEmailAndPassword(
auth, email, password
);
return userCredential.user;
} catch (error) {
console.error('خطأ في تسجيل الدخول:', error.message);
throw error;
}
}
// ===== تسجيل الخروج =====
async function logout() {
await signOut(auth);
console.log('تم تسجيل الخروج');
}
// ===== تسجيل بـ Google =====
async function signInWithGoogle() {
const provider = new GoogleAuthProvider();
const result = await signInWithPopup(auth, provider);
return result.user;
}
// ===== مراقبة حالة المستخدم =====
onAuthStateChanged(auth, (user) => {
if (user) {
console.log('User logged in:', user.email);
} else {
console.log('User logged out');
}
});
// ===== إعادة تعيين كلمة المرور =====
async function resetPassword(email) {
await sendPasswordResetEmail(auth, email);
console.log('تم إرسال رابط إعادة التعيين');
}اختبر فهمك