Firebase Realtime Database هي قاعدة بيانات NoSQL سحابية من Google مع مزامنة فورية للتغييرات عبر اتصال WebSocket دائم. يتم تخزين البيانات كشجرة JSON واحدة، وأي تغيير في أي عقدة يتم إيصاله فوراً لجميع العملاء المتصلين. وفقاً لـ Google, 2026، تدعم Realtime Database ما يصل إلى 200 ألف اتصال متزامن لمثيل واحد. تُقدَّم الخدمة بحد مجاني قدره 1 جيجابايت من التخزين و10 جيجابايت من حركة المرور شهرياً.
النقاط الرئيسية
Firebase Realtime Database هي واحدة من أولى قواعد البيانات السحابية في الوقت الفعلي، التي أطلقتها Google مع Firebase في عام 2012. إنها قاعدة بيانات NoSQL حيث يتم تخزين البيانات كشجرة JSON واحدة يمكن الوصول إليها عبر عنوان URL واحد. تشترك SDKs العميلة (Android وiOS وWeb) في عقد محددة من الشجرة عبر WebSocket وتتلقى التحديثات عند كل تغيير في البيانات — دون الحاجة إلى استقصاء الخادم أو تنفيذ آلية Push مخصصة.
تأسست Firebase الأصلية في عام 2011 بواسطة James Tamplin وAndrew Lee، وكان أول منتج هو Realtime Database نفسها. بعد استحواذ Google في عام 2014 (وفقاً لـ TechCrunch — بمبلغ يتراوح بين 50 و100 مليون دولار)، تم دمج قاعدة البيانات في Google Cloud وحصلت على إنتاجية أعلى بكثير. في عام 2017، أعلنت Google عن Firestore كبديل تطوري، لكن Realtime Database لا تزال مدعومة ومحدثة بنشاط. وفقاً لـ Google (2026)، لا تزال Realtime Database مستخدمة في أكثر من 1.5 مليون مشروع نشط.
خطة Spark (المجانية) تشمل: 1 جيجابايت من التخزين، 10 جيجابايت من البيانات المحملة شهرياً، 100 اتصال متزامن ودعم قاعدة البيانات في منطقة واحدة. في خطة Blaze (الدفع حسب الاستخدام)، يتم الدفع مقابل التخزين الإضافي ($1/جيجابايت)، وحركة المرور ($0.12/جيجابايت)، والاتصالات المتزامنة ($5 لكل 100 ألف فوق الحد). للاختبار، يتوفر أيضاً وضع المحاكاة — firebase emulators:start — الذي يشغل Realtime Database محلياً دون الاتصال بالسحابة.
Realtime Database لا تحتوي على جداول أو مجموعات أو مستندات — كل شيء هو شجرة JSON واحدة يمكن الوصول إليها عبر URL مثل https://project-name-default-rtdb.firebaseio.com/. كل مفتاح في الشجرة هو إما قيمة نهائية (سلسلة نصية، رقم، قيمة منطقية، null) أو عقدة متداخلة بمفاتيح فرعية. لا يدعم محرك قاعدة البيانات JOIN أو الاستعلامات الفرعية أو التجميعات — الاستعلام يعيد دائماً محتويات عقدة واحدة مع جميع عناصرها الفرعية.
بسبب عدم وجود JOIN في Realtime Database، فإن تطبيع البيانات إلزامي. بدلاً من شجرة متداخلة (مستخدم ← قائمة منشوراته)، يتم تقسيم البيانات إلى قوائم مسطحة مع مراجع عبر المفاتيح. هذا هو النهج القياسي: يتم إلغاء تطبيع البيانات بحيث لا يؤدي قراءة عقدة واحدة إلى سحب السياق بأكمله. على سبيل المثال، يتم تخزين قائمة رسائل الدردشة بشكل منفصل عن ملفات تعريف المستخدمين، ويحتوي كل منشور على معرف المؤلف فقط، وليس ملفه الشخصي بالكامل.
| النهج | مثال الهيكل | المشكلة |
|---|---|---|
| متداخل | users/{uid}/posts/{postId}/content | قراءة المستخدم تحمل جميع المنشورات |
| مسطح | posts/{postId}/authorId + users/{uid}/name | يتطلب استعلامين |
| منزوع التطبيع | posts/{postId}/authorName (منسوخ) | تكرار عند التحديث |
يتم تنفيذ الاستعلامات في Realtime Database باستخدام عوامل التصفية (orderByChild وorderByKey وorderByValue وlimitToFirst وlimitToLast وequalTo وstartAt وendAt). على عكس Firestore، يتم إنشاء الفهارس يدوياً عبر قسم Rules (.indexOn). إذا لم يتم الإعلان عن فهرس، فإن الاستعلام مع الترتيب يعيد خطأ PERMISSION_DENIED. تعمل الاستعلامات فقط على حقل واحد — الاستعلامات المركبة (تصفية حسب السعر + ترتيب حسب التاريخ) غير مدعومة. للتصفية المعقدة، غالباً ما يتم تكرار البيانات في عقد مختلفة بمفاتيح ترتيب مختلفة.
الاختيار بين Realtime Database وFirestore هو أحد القرارات المعمارية الشائعة عند بدء مشروع. توصي Google باستخدام Firestore لمعظم التطبيقات الجديدة، لكن Realtime Database تبقى الخيار الأفضل للسيناريوهات التي يكون فيها زمن الوصول الأدنى لنقل البيانات أمراً بالغ الأهمية.
السيناريو الأول — الألعاب متعددة اللاعبين مع مزامنة الحالة (الشطرنج، ألعاب الورق، الأكشن في الوقت الفعلي). زمن وصول Realtime Database هو 10-30 مللي ثانية مقابل 50-100 مللي ثانية لـ Firestore في نفس المنطقة. السيناريو الثاني — الدردشات والمراسلات ذات التردد العالي للرسائل. يتم تسعير Realtime Database حسب حجم البيانات، وليس حسب عدد عمليات الكتابة، مما يجعلها أرخص بكثير من Firestore عند تردد يزيد عن رسالة واحدة في الثانية. السيناريو الثالث — حضور المستخدمين (متصل/غير متصل)، حيث تسمح معالجات onDisconnect في Realtime Database بتعيين الحالة بشكل ذري عند فقدان الاتصال.
وفقاً لـ Google (2026)، حوالي 15% من المشاريع الجديدة على Firebase تختار Realtime Database بوعي — عندما يفهم الفريق بوضوح متطلباته من زمن الوصول وهيكل البيانات والميزانية. في 85% المتبقية من الحالات، تكون Firestore الخيار الأكثر أماناً بفضل قابلية التوسع الأفضل والاستعلامات الأكثر قوة والنسخ التلقائي.
ربط Realtime Database بتطبيق Android يتم بإضافة التبعية firebase-database-ktx في build.gradle. كائن FirebaseDatabase متاح عبر getInstance(url) — يمكنك الاتصال بقواعد بيانات متعددة ضمن مشروع Firebase واحد. بعد التهيئة، يقوم SDK تلقائياً بإنشاء اتصال WebSocket بالخادم ويبدأ مزامنة البيانات.
dependencies {
implementation(platform("com.google.firebase:firebase-bom:33.1.0"))
implementation("com.google.firebase:firebase-database-ktx")
}
// Initialization with custom URL
val database = FirebaseDatabase.getInstance(
"https://my-project-default-rtdb.firebaseio.com/"
)
val ref = database.getReference("chats")
Realtime Database تستخدم كائن DatabaseReference لجميع العمليات. setValue() يكتب البيانات إلى العقدة المحددة، مستبدلاً بالكامل جميع محتوياتها. push() يولد تلقائياً مفتاحاً فريداً (بناءً على طابع زمني) لإضافة عنصر إلى قائمة — هذه هي الطريقة القياسية لإنشاء رسائل الدردشة والمنشورات والسجلات. updateChildren() يعدل عقداً متعددة بشكل ذري في عملية واحدة. addValueEventListener يشترك في تغييرات العقدة ويتلقى استدعاء عند كل تحديث للبيانات.
data class Message(
val author: String = "",
val text: String = "",
val timestamp: Long = ServerValue.TIMESTAMP
)
class ChatRepository(private val ref: DatabaseReference) {
fun sendMessage(author: String, text: String) {
val msg = Message(author = author, text = text)
ref.child("messages").push().setValue(msg)
}
fun observeMessages(): Flow<List<Message>> = callbackFlow {
val listener = ref.child("messages")
.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
val messages = snapshot.children.mapNotNull { it.getValue(Message::class.java) }
trySend(messages)
}
override fun onCancelled(error: DatabaseError) {}
})
awaitClose { ref.removeEventListener(listener) }
}
}
آلية المزامنة في Realtime Database تعتمد على بروتوكول WebSocket (سابقاً — long-polling). يرسل العميل طلباً للاشتراك في عقدة محددة، ويبقي الخادم الاتصال مفتوحاً. عند أي تغيير في البيانات في العقدة المشترك بها، يرسل الخادم JSON الكامل لتلك العقدة إلى العميل. يقوم SDK على العميل تلقائياً بتحديث الحالة المحلية ويستدعي الاستدعاءات المناسبة (onDataChange).
OnDisconnect هي ميزة فريدة في Realtime Database غير موجودة في Firestore. يمكن للمطور تسجيل عملية كتابة سيتم تنفيذها تلقائياً على الخادم عند فقدان اتصال العميل. يُستخدم هذا لحالات الحضور: "user123/status": "online" مع onDisconnect.setValue("offline"). إذا أغلق المستخدم التطبيق أو فقد الاتصال بالإنترنت، سيقوم الخادم تلقائياً بتعيين الحالة إلى "offline" خلال مدة لا تتجاوز 3 دقائق (قابل للتكوين في وحدة تحكم Firebase).
Persistence في Realtime Database يتم تفعيله بسطر واحد: FirebaseDatabase.getInstance().setPersistenceEnabled(true). يقوم SDK بتخزين آخر حالة لجميع العقد المشترك بها على القرص (حتى 10 ميجابايت افتراضياً، قابل للتكوين حتى 100 ميجابايت). عند فقدان الاتصال، يستمر العميل في العمل مع البيانات المخزنة مؤقتاً، وتوضع جميع عمليات الكتابة في قائمة انتظار. عند استعادة الاتصال، يرسل SDK جميع التغييرات المتراكمة إلى الخادم بالترتيب الصحيح (FIFO).
وفقاً لـ Google (2026)، فإن التطبيقات التي لديها تخزين مؤقت للثبات مفعل تقل احتمالية فقدان بيانات المستخدم عند فقدان الاتصال بنسبة 40%. ومع ذلك، إذا تراكم لدى العميل أكثر من 1000 عملية معلقة، قد يرفضها الخادم جميعاً ويطلب مزامنة كاملة — هذه آلية حماية ضد العملاء القدامى.
قواعد الأمان في Realtime Database هي تكوين JSON يصف من يمكنه قراءة وكتابة البيانات في كل عقدة وتحت أي ظروف. تعمل القواعد على خادم Google ويتم تنفيذها قبل كل عملية. افتراضياً (في الإنتاج)، يُوصى بتعيين القواعد في وضع "مغلق" — فقط المستخدمون الموثقون لديهم حق الوصول.
تكتب قواعد Realtime Database بتنسيق JSON مع أقسام .read و .write و .validate و .indexOn. على عكس Firestore (الذي يستخدم صيغة match)، تستخدم Realtime Database كائنات متداخلة تعكس هيكل البيانات. تتحقق الشروط من auth (المصادقة) و data (البيانات الموجودة) و newData (البيانات الجديدة عند الكتابة) و now (وقت الخادم). تسمح قواعد التحقق (.validate) بالتحقق من الأنواع ونطاقات القيم وهيكل البيانات.
{
"rules": {
"users": {
"$uid": {
".read": "auth.uid === $uid",
".write": "auth.uid === $uid",
".validate": "newData.hasChildren(['name', 'email'])"
}
},
"messages": {
".indexOn": ["timestamp"],
"$msgId": {
".read": true,
".write": "auth.uid !== null",
".validate": "newData.child('text').isString() && newData.child('text').val().length <= 500"
}
}
}
}
قواعد Realtime Database تُورث بشكل متتالي — إذا كان .read = false في المستوى العلوي، فإن جميع العقد الفرعية غير متاحة للقراءة بغض النظر عن قواعدها الخاصة. توفر Firebase محاكياً للقواعد في وحدة التحكم حيث يمكن اختبار العمليات برموز مصادقة مختلفة قبل النشر. يُوصى دائماً باختبار القواعد في المحاكي — خطأ في قاعدة قد يفتح الوصول إلى البيانات الخاصة لجميع المستخدمين. وفقاً لـ Google (2026)، 40% من تسريبات البيانات في مشاريع Firebase سببها قواعد أمان تم تكوينها بشكل غير صحيح.
الأسئلة الشائعة
ما يصل إلى 200 ألف اتصال متزامن لمثيل قاعدة بيانات واحد. عند تجاوز الحد، يتم حظر الاتصالات الجديدة. للتوسع، يتم استخدام التقسيم عبر قواعد بيانات متعددة.
استخدم onDisconnect — سجل عملية كتابة لـ "offline" عند فقدان الاتصال. سيقوم الخادم بتنفيذها تلقائياً عند انقطاع WebSocket. تابع الاتصال بشكل منفصل عبر .info/connected.
تحقق من .indexOn في قواعد الأمان — بدون فهرس معلن، استعلام مع orderByChild سيعيد PERMISSION_DENIED. تأكد أيضاً من أن البيانات تُكتب في العقدة الصحيحة وأن القارئ لديه صلاحيات .read.
توفر وحدة تحكم Firebase تصديراً من Realtime Database إلى Firestore بزر واحد. يتم تحويل هيكل JSON إلى مجموعات ومستندات. للترحيل المخصص، استخدم Admin SDK.
لا، تخزين كلمات المرور في Realtime Database محظور بموجب قواعد أمان Google. استخدم Firebase Auth للمصادقة — يتم تخزين تجزئات كلمات المرور في مخزن معزول لا يمكن الوصول إليه عبر SDK لـ Realtime Database.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا