أنت تبني تطبيقًا وتحتاج إلى تسجيل دخول المستخدمين، مزامنة البيانات في الوقت الفعلي، وتخزين الملفات. يمكنك إدارة الخوادم وقواعد البيانات يدويًا، أو تختصر الطريق وتستخدم Firebase لتبسيط كل ما سبق. هذا الدليل العملي يوضح لك كيفية دمج واختبار خدمات Firebase في مشروعك خطوة بخطوة، مع أمثلة برمجية وقواعد أمان جاهزة للإنتاج.
💡يصبح اختبار واجهات برمجة تطبيقات Firebase أسهل باستخدام أدوات عميل API المناسبة. يتيح لك Apidog تنظيم نقاط النهاية، واختبار تدفقات المصادقة، ومشاركة المجموعات مع فريقك. سنوضح أين يتناسب ذلك بشكل طبيعي في سير العمل.
ما هي واجهة برمجة تطبيقات Firebase ولماذا هي مهمة؟
Firebase ليست مجرد API واحدة، بل منصة متكاملة تشمل عدة خدمات Backend تُدار بالكامل، تصل إليها عبر SDKs موحدة أو REST endpoints. هذا يسمح لك بالتركيز على بناء الميزات بدون عبء إدارة الخوادم أو قواعد البيانات.
خدمات Firebase الأساسية
| الخدمة | الغرض | نوع واجهة برمجة التطبيقات (API) |
|---|---|---|
| المصادقة | تسجيل دخول المستخدم والهوية | SDK + REST |
| قاعدة بيانات Firestore | قاعدة بيانات مستندات NoSQL | SDK + REST |
| قاعدة بيانات Realtime | مزامنة JSON في الوقت الفعلي | SDK + REST |
| التخزين السحابي | تخزين الملفات وCDN | SDK + REST |
| وظائف Cloud Functions | الحوسبة بلا خادم (Serverless) | واجهة سطر الأوامر (Deployment CLI) |
| الاستضافة | استضافة الويب الثابتة | واجهة سطر الأوامر (Deployment CLI) |
| الرسائل السحابية | إشعارات الدفع | HTTP v1 API |
متى يكون Firebase هو الخيار المناسب
استخدم Firebase عندما:
- تحتاج مزامنة فورية (دردشة، تعاون، تحديثات مباشرة)
- تريد تطبيقًا بدون خوادم (Serverless)
- تطور تطبيقات جوال أو ويب بسرعة
- تحتاج دعم العمل بدون اتصال (Offline)
- تريد مصادقة مدمجة (Google, Apple, Email, Phone)
تجنب Firebase عندما:
- تحتاج استعلامات علائقية معقدة (استخدم PostgreSQL)
- لديك متطلبات خصوصية بيانات صارمة (مناطق استضافة محدودة)
- تحتاج إمكانيات SQL كاملة
- التكلفة على نطاق كبير أهم من سرعة التطوير
هندسة Firebase API
Firebase يستخدم طبقة SDK على العميل تختصر استدعاء REST وتدير المصادقة والتخزين المؤقت:
┌───────────────────────┐
│ تطبيقك │
├───────────────────────┤
│ Firebase SDK │
│ - إدارة التوكنات │
│ - تخزين مؤقت │
│ - مستمعو الوقت الفعلي│
└───────────────────────┘
│ HTTPS/WebSocket
▼
┌──────────────────────────┐
│ Firebase Backend │
└──────────────────────────┘
مصادقة Firebase: التنفيذ خطوة بخطوة
الخطوة 1: إنشاء مشروع Firebase
- اذهب إلى وحدة تحكم Firebase
- انقر "إضافة مشروع"، أدخل اسم المشروع
- فعّل Google Analytics (اختياري)
- انتظر حتى تظهر لوحة تحكم المشروع
الخطوة 2: تسجيل تطبيقك
تطبيقات الويب
// Firebase Console > Project Settings > General
const firebaseConfig = {
apiKey: "AIzaSyDxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
authDomain: "your-app.firebaseapp.com",
projectId: "your-app",
storageBucket: "your-app.appspot.com",
messagingSenderId: "123456789012",
appId: "1:123456789012:web:abc123def456"
};
import { initializeApp } from 'firebase/app';
const app = initializeApp(firebaseConfig);
تطبيقات iOS
- حمّل
GoogleService-Info.plistوأضفه لمشروع Xcode.
تطبيقات Android
- حمّل
google-services.jsonوضعه في مجلدapp/. - أضف في
build.gradle:
buildscript {
dependencies {
classpath 'com.google.gms:google-services:4.4.0'
}
}
plugins {
id 'com.google.gms.google-services'
}
الخطوة 3: تمكين طرق المصادقة
في Firebase Console > المصادقة > طرق تسجيل الدخول:
- فعّل Email/Password
- فعّل Google (وأضف SHA-1/Bundle ID)
- فعّل Apple إذا لزم الأمر
- فعّل Phone (يحتاج فاتورة)
الخطوة 4: تنفيذ تدفق المصادقة
تسجيل مستخدم جديد بالبريد الإلكتروني
import {
createUserWithEmailAndPassword,
getAuth,
updateProfile
} from 'firebase/auth';
const auth = getAuth(app);
async function signUp(email, password, displayName) {
try {
const userCredential = await createUserWithEmailAndPassword(
auth,
email,
password
);
await updateProfile(userCredential.user, { displayName });
return userCredential.user;
} catch (error) {
switch (error.code) {
case 'auth/email-already-in-use':
throw new Error('هذا البريد الإلكتروني مسجل بالفعل');
case 'auth/weak-password':
throw new Error('يجب أن تتكون كلمة المرور من 6 أحرف على الأقل');
default:
throw new Error('فشل التسجيل: ' + error.message);
}
}
}
تسجيل الدخول بالبريد الإلكتروني/كلمة المرور
import { signInWithEmailAndPassword, signOut } from 'firebase/auth';
async function signIn(email, password) {
try {
const userCredential = await signInWithEmailAndPassword(
auth,
email,
password
);
return userCredential.user;
} catch (error) {
throw new Error('فشل تسجيل الدخول');
}
}
async function logOut() {
await signOut(auth);
}
تسجيل الدخول عبر Google
import { GoogleAuthProvider, signInWithPopup } from 'firebase/auth';
async function signInWithGoogle() {
const provider = new GoogleAuthProvider();
provider.addScope('email');
provider.addScope('profile');
try {
const result = await signInWithPopup(auth, provider);
return result.user;
} catch (error) {
throw new Error('فشل تسجيل الدخول عبر Google');
}
}
الخطوة 5: حماية المسارات بحالة المصادقة
import { onAuthStateChanged } from 'firebase/auth';
onAuthStateChanged(auth, (user) => {
if (user) {
window.location.href = '/dashboard';
} else {
window.location.href = '/login';
}
});
أخطاء المصادقة الشائعة
- عدم التعامل مع تحديث التوكن.
- كشف بيانات اعتماد المشرف في كود العميل.
- تخطي التحقق من البريد الإلكتروني:
import { sendEmailVerification } from 'firebase/auth';
async function sendVerificationEmail(user) {
await sendEmailVerification(user);
}
if (!auth.currentUser.emailVerified) {
// تقييد الوصول
}
قاعدة بيانات Firestore: العمليات الأساسية
تهيئة Firestore
import { getFirestore } from 'firebase/firestore';
const db = getFirestore(app);
إنشاء مستند
import { collection, addDoc, setDoc, doc } from 'firebase/firestore';
async function createUser(userData) {
const docRef = await addDoc(collection(db, 'users'), userData);
return docRef.id;
}
async function createUserWithId(userId, userData) {
await setDoc(doc(db, 'users', userId), userData);
}
قراءة مستند أو استعلام
import { getDoc, getDocs, query, where, orderBy, limit } from 'firebase/firestore';
async function getUser(userId) {
const docSnap = await getDoc(doc(db, 'users', userId));
if (docSnap.exists()) return docSnap.data();
throw new Error('المستخدم غير موجود');
}
async function getUsersByRole(role) {
const q = query(
collection(db, 'users'),
where('role', '==', role),
orderBy('createdAt', 'desc'),
limit(10)
);
const querySnapshot = await getDocs(q);
return querySnapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
}
تحديث وحذف مستند
import { updateDoc, increment, arrayUnion, arrayRemove, deleteDoc } from 'firebase/firestore';
async function updateUser(userId, updates) {
const userRef = doc(db, 'users', userId);
await updateDoc(userRef, updates);
}
await updateUser('userId123', { loginCount: increment(1), tags: arrayUnion('premium') });
await updateUser('userId123', { tags: arrayRemove('beta-tester') });
async function deleteUser(userId) {
await deleteDoc(doc(db, 'users', userId));
}
مستمعو الوقت الفعلي
import { onSnapshot } from 'firebase/firestore';
const unsubscribe = onSnapshot(
doc(db, 'users', userId),
(doc) => { /* تحديث واجهة المستخدم */ }
);
unsubscribe();
قواعد أمان Firestore
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
function isAuthenticated() { return request.auth != null; }
function isOwner(userId) { return request.auth.uid == userId; }
match /users/{userId} {
allow read: if isAuthenticated();
allow create: if isAuthenticated() && isOwner(userId);
allow update, delete: if isOwner(userId);
}
match /posts/{postId} {
allow read: if true;
allow create: if isAuthenticated();
allow update, delete: if resource.data.authorId == request.auth.uid;
}
match /users/{userId}/private/{document} {
allow read, write: if isOwner(userId);
}
}
}
قيود الاستعلام
- لا توجد استعلامات OR مباشرة: استخدم استعلامات متعددة وادمج النتائج في العميل.
- عمليات البحث بالنص الكامل: استخدم Algolia أو Meilisearch.
- الاستعلامات المركبة تحتاج فهارس مخصصة.
Cloud Functions: منطق الواجهة الخلفية بلا خادم
الإعداد
npm install -g firebase-tools
firebase login
firebase init functions
وظائف HTTP (API)
const { onRequest } = require('firebase-functions/v2/https');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
exports.getUserProfile = onRequest(async (req, res) => {
const authHeader = req.headers.authorization || '';
const token = authHeader.split('Bearer ')[1];
if (!token) return res.status(401).json({ error: 'غير مصرح به' });
try {
const decodedToken = await admin.auth().verifyIdToken(token);
const userId = decodedToken.uid;
const userDoc = await db.collection('users').doc(userId).get();
if (!userDoc.exists) return res.status(404).json({ error: 'المستخدم غير موجود' });
res.json({ success: true, data: { id: userId, ...userDoc.data() } });
} catch {
res.status(401).json({ error: 'رمز مميز غير صالح' });
}
});
نشر الوظيفة
firebase deploy --only functions:getUserProfile
استدعاء الوظيفة من العميل
async function getUserProfile(token) {
const response = await fetch(
'https://us-central1-your-app.cloudfunctions.net/getUserProfile',
{ headers: { 'Authorization': `Bearer ${token}` } }
);
return await response.json();
}
مشغلات قاعدة البيانات
const { onDocumentWritten } = require('firebase-functions/v2/firestore');
exports.onUserUpdate = onDocumentWritten(
'users/{userId}',
async (event) => {
const userId = event.params.userId;
const before = event.data?.before?.data();
const after = event.data?.after?.data();
if (before?.email !== after?.email) {
// منطق إشعار البريد الإلكتروني
}
}
);
الوظائف المجدولة
const { onSchedule } = require('firebase-functions/v2/scheduler');
exports.dailyCleanup = onSchedule('every 24 hours', async () => {
// حذف الإشعارات القديمة
});
تهيئة البيئة
firebase functions:config:set stripe.secret="sk_test_xxx"
const config = require('firebase-functions/config');
const stripe = require('stripe')(config.stripe.secret);
التخزين السحابي: تحميل وإدارة الملفات
إعداد قواعد التخزين
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /users/{userId}/{allPaths=**} {
allow read: if true;
allow write, delete: if request.auth.uid == userId;
}
match /public/{allPaths=**} {
allow read: if true;
allow write: if false;
}
}
}
تحميل ملف (العميل)
import { getStorage, ref, uploadBytesResumable, getDownloadURL } from 'firebase/storage';
const storage = getStorage(app);
async function uploadProfileImage(userId, file) {
const storageRef = ref(storage, `users/${userId}/profile/${file.name}`);
const uploadTask = uploadBytesResumable(storageRef, file);
return new Promise((resolve, reject) => {
uploadTask.on(
'state_changed',
(snapshot) => { /* تتبع التقدم */ },
(error) => { reject(error); },
async () => {
const downloadURL = await getDownloadURL(uploadTask.snapshot.ref);
resolve(downloadURL);
}
);
});
}
// الاستخدام
const imageUrl = await uploadProfileImage(auth.currentUser.uid, file);
await updateDoc(doc(db, 'users', auth.currentUser.uid), { profileImage: imageUrl });
تنزيل/حذف ملف
import { getDownloadURL, deleteObject } from 'firebase/storage';
async function getProfileImage(userId) {
const imageRef = ref(storage, `users/${userId}/profile/avatar.png`);
return await getDownloadURL(imageRef);
}
async function deleteProfileImage(userId) {
const imageRef = ref(storage, `users/${userId}/profile/avatar.png`);
await deleteObject(imageRef);
}
اختبار واجهات Firebase API باستخدام Apidog
Firebase توفر REST API لكل خدمة. يمكنك اختبارها مباشرة عبر أدوات مثل Apidog:
استيراد نقاط النهاية
- افتح Apidog
- أنشئ مشروع "Firebase API"
- استورد OpenAPI أو أضف نقطة نهاية يدوياً
مثال Firestore REST
POST https://firestore.googleapis.com/v1/projects/{projectId}/databases/(default)/documents
Authorization: Bearer {oauth2_token}
Content-Type: application/json
{
"fields": {
"name": { "stringValue": "John" }
}
}
مثال مصادقة
POST https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key={api_key}
Content-Type: application/json
{
"email": "user@example.com",
"password": "secret123",
"returnSecureToken": true
}
اختبار تدفق المصادقة
- أنشئ طلب "تسجيل الدخول" (POST)
- أضف بيانات المستخدم
- احفظ التوكن في متغير بيئة
- استخدم
{{token}}في الطلبات التالية
تصحيح قواعد الأمان
استخدم Firebase Emulator Suite:
firebase emulators:start
ثم اختبر مقابل http://localhost:8080
أفضل ممارسات الإنتاج
1. معالجة الأخطاء
async function firestoreWithRetry(operation, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await operation();
} catch (error) {
if (error.code === 'unavailable' || error.code === 'deadline-exceeded') {
await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
continue;
}
throw error;
}
}
}
2. تحسين الاستعلامات
أضف فهارس مركبة للاستعلامات متعددة الحقول. Firestore ينبهك عند الحاجة لفهرس.
3. عمليات الدفعة
import { writeBatch } from 'firebase/firestore';
async function bulkUpdate(userIds, updates) {
const batch = writeBatch(db);
userIds.forEach(id => batch.update(doc(db, 'users', id), updates));
await batch.commit();
}
4. مراقبة التكاليف
| الخدمة | الفئة المجانية | المدفوعة |
|---|---|---|
| Firestore | 50 ألف قراءة/يوم | 0.036$/100 ألف قراءة |
| التخزين | 5 جيجابايت | 0.023$/جيجابايت |
| الوظائف | 2 مليون استدعاء | 0.40$/مليون |
| المصادقة | 10 آلاف/شهر | 0.0055$/100 ألف |
عيّن تنبيهات الميزانية من Google Cloud Console.
5. تأمين حسابات الخدمة
لا تضع بيانات اعتماد المشرف في كود العميل أبداً. استخدمها فقط على الخادم.
6. دعم عدم الاتصال
import { enableMultiTabIndexedDbPersistence } from 'firebase/firestore';
enableMultiTabIndexedDbPersistence(db)
.catch((err) => { /* معالجة الخطأ */ });
مشكلات وحلول Firebase API الشائعة
1. أخطاء رفض الإذن
- تحقق من القواعد في Console
- تحقق من تطابق
request.auth.uid - استخدم Rules Playground للاختبار
2. انتهاء صلاحية التوكن
const user = auth.currentUser;
if (user) await user.getIdToken(true);
3. بطء الاستجابة (البدء البارد)
- استخدم وظيفة keep-warm مع جدولة ping كل دقيقة.
4. استعلامات فارغة
- تحقق من وجود الفهارس أو صحة ترتيب الحقول.
حالات استخدام حقيقية
- Fintech: إشعارات معاملات فورية باستخدام Firestore + Cloud Functions
- تجارة إلكترونية: مزامنة المخزون عبر منصات متعددة، مع دعم العمل بدون اتصال
- SaaS: مصادقة متعددة المستأجرين وتخصيص الأذونات عبر Cloud Functions
الخاتمة
دمج Firebase في تطبيقك يتطلب فهم مصادقة JWT، عمليات Firestore، وظائف Cloud Functions، والتخزين السحابي. استخدم القواعد البرمجية أعلاه، اختبر واجهاتك عبر Apidog، وطبّق قواعد الأمان والدفعات وتحسين الاستعلامات للحصول على تطبيق جاهز للإنتاج.
الأسئلة الشائعة
هل Firebase مجاني للاستخدام؟
نعم، يوجد طبقة مجانية (Spark) تشمل 5 جيجابايت تخزين، 50 ألف قراءة Firestore يومياً، و2 مليون استدعاء وظائف شهرياً. الخطط المدفوعة (Blaze) بحسب الاستخدام.
هل يمكنني استخدام Firebase مع قواعد بيانات موجودة؟
نعم، عبر Firebase Extensions أو Cloud Functions للربط مع أنظمة خارجية.
كيف أرحل من Firebase إلى منصة أخرى؟
صدّر بياناتك عبر CLI أو Dataflow ثم استوردها في النظام الجديد.
هل يدعم Firebase GraphQL؟
ليس رسمياً؛ استخدم أدوات مثل firestore-graphql أو طبقة Cloud Functions + Apollo Server.
هل يمكن استخدام Firebase محلياً؟
لا، Firebase يعمل فقط على Google Cloud. للبدائل الذاتية: Appwrite أو Supabase أو Nhost.
كيف أتعامل مع تحميل ملفات أكبر من 100 ميجابايت؟
استخدم التحميل القابل للاستئناف. للملفات الضخمة استخدم Google Cloud Storage مباشرة.
ماذا يحدث إذا تجاوزت حدود استعلام Firestore؟
ستحصل على خطأ FAILED_PRECONDITION. أنشئ الفهارس المطلوبة أو عدل الاستعلامات.
هل Firebase متوافق مع اللائحة العامة لحماية البيانات (GDPR)؟
نعم، مع تفعيل مناطق التخزين وتطبيق حذف/تصدير بيانات المستخدم وتوقيع اتفاقية معالجة البيانات من Google.




Top comments (0)