تخطَّ إلى المحتوى

تسجيل الدخول في Firebase: Authentication

الدرس 4 من 9 · Firebase

بناء نظام تسجيل دخول من الصفر عمل صعب وخطير: تخزين كلمات المرور بأمان، واستعادة الحسابات، والحماية من الاختراق. أخطاء صغيرة هنا قد تكشف بيانات كل المستخدمين. Firebase Authentication يقدم لك كل هذا جاهزاً ومختبراً، بأسطر قليلة. في هذا الدرس ستبني إنشاء الحساب وتسجيل الدخول والخروج، وستربط ذلك بقواعد الأمان لحماية بياناتك.

في Firebase Console:

  1. اختر Authentication ثم Get started.
  2. من تبويب Sign-in method، فعّل Email/Password.

وهناك طرق كثيرة أخرى تفعّلها بنفس الطريقة: الدخول بحساب Google، أو رقم الهاتف، أو Apple، وغيرها.

import { createUserWithEmailAndPassword, updateProfile } from 'firebase/auth';
const cred = await createUserWithEmailAndPassword(auth, 'sara@example.com', 'Strong#Pass2026');
console.log(cred.user.email);
await updateProfile(cred.user, { displayName: 'سارة' });
console.log(auth.currentUser.displayName);
الناتج
sara@example.com
سارة
  • createUserWithEmailAndPassword: ينشئ الحساب، ويسجل دخوله تلقائياً.
  • cred.user: بيانات المستخدم الجديد، وأهمها uid: معرّف فريد للمستخدم، ستستخدمه لربط بياناته في Firestore.
  • updateProfile: يضيف اسماً معروضاً أو صورة للحساب.
  • auth.currentUser: المستخدم المسجل حالياً، أو null إن لم يوجد.

Firebase لا يخزن كلمة المرور نصاً عادياً أبداً، بل بطريقة مشفرة لا يمكن عكسها. حتى أنت كمطور لا تستطيع رؤيتها.

العمليات قد تفشل، وكل فشل له رمز (Code) تستخدمه لعرض رسالة مناسبة:

try {
await createUserWithEmailAndPassword(auth, 'sara@example.com', '123');
} catch (e) {
console.log(e.code);
}
الناتج
auth/weak-password
الرمز المعنى رسالة مقترحة للمستخدم
auth/weak-password كلمة مرور أقل من 6 حروف «كلمة المرور ضعيفة، استخدم 6 حروف على الأقل»
auth/email-already-in-use البريد مسجل مسبقاً «هذا البريد مستخدم، جرّب تسجيل الدخول»
auth/invalid-email صيغة البريد خاطئة «اكتب بريداً صحيحاً»
auth/invalid-credential بيانات الدخول خاطئة «البريد أو كلمة المرور غير صحيحة»
import { signInWithEmailAndPassword, signOut } from 'firebase/auth';
await signInWithEmailAndPassword(auth, 'sara@example.com', 'Strong#Pass2026');
// ... لاحقاً
await signOut(auth);

متابعة حالة المستخدم: onAuthStateChanged

Section titled “متابعة حالة المستخدم: onAuthStateChanged”

كيف يعرف تطبيقك أن المستخدم دخل أو خرج؟ لا تعتمد على فحص currentUser مرة واحدة، بل استمع للتغيير:

import { onAuthStateChanged } from 'firebase/auth';
onAuthStateChanged(auth, (user) => {
if (user) {
console.log('مسجل الدخول:', user.email);
} else {
console.log('زائر');
}
});

الدالة تُنفَّذ فوراً بالحالة الحالية، ثم كلما تغيرت. في تجربتنا: كانت سارة مسجلة، ثم خرجت، ثم دخلت من جديد، فوصلت ثلاث حالات بالترتيب: sara@example.com ثم null ثم sara@example.com.

هذا المكان المثالي لتغيير الواجهة: إظهار زر «دخول» للزائر، واسم المستخدم وزر «خروج» للمسجل. وFirebase يتذكر المستخدم تلقائياً، فإذا أغلق المتصفح وفتحه، يبقى مسجلاً دون أن يكتب كلمة المرور.

تخيّل onAuthStateChanged مثل حارس البوابة الذي يبلغك فوراً كلما دخل أحد أو خرج، بدلاً من أن تذهب أنت للسؤال كل دقيقة.

هنا تكتمل الصورة. في قواعد Firestore، المتغير request.auth يحمل بيانات المستخدم الذي يرسل الطلب، أو null للزائر:

firestore.rules
match /posts/{postId} {
allow read: if true;
allow create: if request.auth != null;
allow update, delete: if request.auth != null
&& request.auth.uid == resource.data.authorId;
}
  • القراءة: متاحة للجميع.
  • الإنشاء: للمسجلين فقط.
  • التعديل والحذف: لصاحب المنشور فقط، بمقارنة uid المستخدم بحقل authorId في المنشور.

وعند إنشاء منشور، نخزن فيه معرّف صاحبه:

await addDoc(collection(db, 'posts'), {
text: 'مرحباً',
authorId: auth.currentUser.uid,
createdAt: serverTimestamp()
});

جربنا القواعد فعلاً على المحاكي:

  • زائر حاول إنشاء منشور ← رُفض بالخطأ permission-denied.
  • سارة بعد تسجيل دخولها ← نجح الإنشاء.
  • مستخدم آخر (عمر) حاول تعديل منشور سارة ← رُفض بالخطأ permission-denied.

و serverTimestamp() تسجل وقت الخادم الحقيقي، لا وقت جهاز المستخدم الذي قد يكون مضبوطاً خطأ.

  1. فعّل Email/Password في مشروعك، أو استخدم المحاكي.
  2. ابنِ صفحة HTML فيها نموذج بحقلي البريد وكلمة المرور، وزرين: «إنشاء حساب» و«دخول».
  3. اعرض رسالة عربية مناسبة لكل رمز خطأ.
  4. استخدم onAuthStateChanged لإظهار «أهلاً يا …» وزر «خروج» للمسجل.
  5. اكتب قاعدة تسمح لكل مستخدم بقراءة وكتابة مستند واحد فقط هو users/{uid} الخاص به.
  • فحص currentUser فور تحميل الصفحة: قد يكون null لأن Firebase لم يتحقق بعد. استخدم onAuthStateChanged.
  • عرض رسائل الأخطاء الإنجليزية كما هي: حوّل الرموز لرسائل عربية مفهومة.
  • الاعتماد على الواجهة للحماية: القواعد هي الحماية الوحيدة الحقيقية.

سؤال

ما أفضل طريقة لمعرفة هل المستخدم مسجل الدخول وتحديث الواجهة عند تغيّر ذلك؟

سؤال

في قواعد الأمان، ماذا يعني الشرط request.auth.uid == resource.data.authorId؟

  • فعّل طرق الدخول من Console، و Firebase يخزن كلمات المرور بأمان نيابة عنك.
  • createUserWithEmailAndPassword و signInWithEmailAndPassword و signOut للعمليات الأساسية.
  • رموز الأخطاء مثل auth/weak-password تُحوَّل لرسائل عربية واضحة.
  • onAuthStateChanged يتابع حالة المستخدم، و uid معرّفه الفريد.
  • request.auth في قواعد الأمان يربط البيانات بأصحابها، وهي الحماية الحقيقية الوحيدة.