خطوات الإعداد الكاملة
1. إنشاء المشروع
في console.firebase.google.com أنشئ مشروعاً جديداً واحصل على ملف التكوين.
2. تثبيت الـ SDK
عبر CDN أو npm install firebase حسب نوع مشروعك.
3. التهيئة
انسخ firebaseConfig من لوحة المشروع والصقها في كودك.
firebase-config.js
// ─── تثبيت عبر CDN (في HTML) ───
// <script type="module"> ... </script>
import { initializeApp } from "https://www.gstatic.com/firebasejs/10.12.0/firebase-app.js";
import { getFirestore } from "https://www.gstatic.com/firebasejs/10.12.0/firebase-firestore.js";
import { getAuth } from "https://www.gstatic.com/firebasejs/10.12.0/firebase-auth.js";
import { getStorage } from "https://www.gstatic.com/firebasejs/10.12.0/firebase-storage.js";
// ─── معلومات مشروعك (من Firebase Console) ───
const firebaseConfig = {
apiKey: "AIzaSy...",
authDomain: "myapp.firebaseapp.com",
projectId: "myapp-12345",
storageBucket: "myapp-12345.appspot.com",
messagingSenderId: "123456789",
appId: "1:123456789:web:abcdef"
};
// ─── تهيئة Firebase ───
const app = initializeApp(firebaseConfig);
const db = getFirestore(app); // Firestore Database
const auth = getAuth(app); // Authentication
const storage = getStorage(app); // File Storage
export { db, auth, storage };
⚠️ لا تضع الـ apiKey في مستودع GitHub عام. استخدم Environment Variables في مشاريع الـ Production.
نظام المصادقة الكامل
auth.js — تسجيل / دخول / مراقبة
import { auth } from "./firebase-config.js";
import {
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
signOut,
onAuthStateChanged,
updateProfile,
sendPasswordResetEmail,
GoogleAuthProvider,
signInWithPopup
} from "firebase/auth";
// ─── 1. إنشاء حساب جديد ───
async function register(email, password, displayName) {
try {
const cred = await createUserWithEmailAndPassword(auth, email, password);
// تحديث الاسم فور الإنشاء
await updateProfile(cred.user, { displayName });
console.log("✅ تم إنشاء الحساب:", cred.user.uid);
return cred.user;
} catch (err) {
const msgs = {
'auth/email-already-in-use': "الإيميل مستخدم بالفعل",
'auth/weak-password': "كلمة المرور ضعيفة جداً (6+ أحرف)",
'auth/invalid-email': "صيغة الإيميل غير صحيحة",
};
throw new Error(msgs[err.code] || err.message);
}
}
// ─── 2. تسجيل الدخول ───
async function login(email, password) {
try {
const cred = await signInWithEmailAndPassword(auth, email, password);
window.location.href = "dashboard.html"; // redirect بعد الدخول
} catch (err) {
const msgs = {
'auth/user-not-found': "لا يوجد حساب بهذا الإيميل",
'auth/wrong-password': "كلمة المرور غير صحيحة",
'auth/too-many-requests': "محاولات كثيرة، انتظر قليلاً",
};
throw new Error(msgs[err.code] || err.message);
}
}
// ─── 3. الدخول بـ Google OAuth ───
async function loginWithGoogle() {
const provider = new GoogleAuthProvider();
const cred = await signInWithPopup(auth, provider);
console.log("مسجل كـ:", cred.user.email);
}
// ─── 4. مراقب الحالة (أهم دالة في Auth) ───
onAuthStateChanged(auth, (user) => {
if (user) {
console.log(`مرحباً ${user.displayName} (${user.uid})`);
loadUserData(user.uid); // جلب بيانات المستخدم من Firestore
} else {
window.location.href = "login.html"; // redirect لو لم يدخل
}
});
// ─── 5. تسجيل الخروج وإعادة التعيين ───
const logout = () => signOut(auth);
const resetPassword = (email) => sendPasswordResetEmail(auth, email);
Firestore — CRUD كامل
firestore.js — القراءة / الكتابة / الحذف / Real-time
import { db } from "./firebase-config.js";
import {
collection, doc, addDoc, setDoc,
getDoc, getDocs, updateDoc, deleteDoc,
onSnapshot, query, where, orderBy, limit,
serverTimestamp, increment
} from "firebase/firestore";
const playersRef = collection(db, "players");
// ─── CREATE — إضافة وثيقة (ID تلقائي) ───
async function addPlayer(data) {
const docRef = await addDoc(playersRef, {
...data,
createdAt: serverTimestamp(), // وقت السيرفر لا العميل
score: 0
});
console.log("ID الجديد:", docRef.id);
}
// CREATE بـ ID محدد (مثلاً UID المستخدم)
async function createUserProfile(uid, data) {
await setDoc(doc(db, "users", uid), {
...data, createdAt: serverTimestamp()
});
}
// ─── READ — قراءة وثيقة واحدة ───
async function getPlayer(id) {
const snap = await getDoc(doc(db, "players", id));
if (snap.exists()) return { id: snap.id, ...snap.data() };
throw new Error("اللاعب غير موجود");
}
// READ — استعلام متقدم مع فلترة وترتيب
async function getTopPlayers() {
const q = query(
playersRef,
where("rank", "==", "Gold"),
where("score", ">=", 1000),
orderBy("score", "desc"),
limit(10)
);
const snap = await getDocs(q);
return snap.docs.map(d => ({ id: d.id, ...d.data() }));
}
// ─── UPDATE ───
async function updateScore(id, points) {
await updateDoc(doc(db, "players", id), {
score: increment(points), // زيادة ذرية آمنة
lastSeen: serverTimestamp()
});
}
// ─── DELETE ───
const deletePlayer = (id) =>
deleteDoc(doc(db, "players", id));
// ─── REAL-TIME LISTENER — يحدّث تلقائياً ───
function watchLeaderboard(onUpdate) {
const q = query(playersRef, orderBy("score", "desc"), limit(20));
return onSnapshot(q, (snap) => {
const players = snap.docs.map(d => ({ id: d.id, ...d.data() }));
onUpdate(players); // يُستدعى كلما تغيرت البيانات
});
// ✅ لإيقاف الاستماع: const unsub = watchLeaderboard(...); unsub();
}
🔒 Security Rules: في Firestore، اكتب قواعد تتحقق من auth.uid مثل: allow write: if request.auth.uid == userId;
Realtime Database — البيانات الحية الفورية
import { getDatabase, ref, set, push, onValue, get, remove, update }
from "firebase/database";
const rtdb = getDatabase(app);
// ─── كتابة بمسار محدد ───
await set(ref(rtdb, `users/${uid}`), {
name: "Ahmed", online: true
});
// ─── إضافة بـ ID تلقائي (مثل Array) ───
const newRef = await push(ref(rtdb, "messages"), {
text: "مرحباً!", time: Date.now()
});
// ─── قراءة مرة واحدة ───
const snap = await get(ref(rtdb, `users/${uid}`));
if (snap.exists()) console.log(snap.val());
// ─── مستمع Real-time ───
onValue(ref(rtdb, "game/state"), (snap) => {
renderGame(snap.val()); // يُشغَّل فور أي تغيير
});
// ─── Presence System (هل المستخدم متصل؟) ───
import { serverTimestamp, onDisconnect } from "firebase/database";
const presRef = ref(rtdb, `presence/${uid}`);
await set(presRef, { online: true, lastSeen: serverTimestamp() });
onDisconnect(presRef).set({ online: false, lastSeen: serverTimestamp() });
Firebase Storage — رفع الملفات
import { storage } from "./firebase-config.js";
import { ref as storageRef, uploadBytesResumable,
getDownloadURL, deleteObject } from "firebase/storage";
// ─── رفع صورة مع شريط التقدم ───
async function uploadAvatar(uid, file, onProgress) {
const ext = file.name.split(".").pop();
const path = `avatars/${uid}.${ext}`;
const sRef = storageRef(storage, path);
const task = uploadBytesResumable(sRef, file);
return new Promise((resolve, reject) => {
task.on("state_changed",
(snap) => { // أثناء الرفع
const pct = (snap.bytesTransferred / snap.totalBytes) * 100;
onProgress(Math.round(pct));
},
reject, // عند الخطأ
async () => { // بعد الانتهاء
const url = await getDownloadURL(task.snapshot.ref);
resolve(url); // رابط قابل للنشر
}
);
});
}