Firebase Realtime DB — ما هو، الهندسة المعمارية والعمل مع JSON

المؤلف: IT Sectr نُشر: 2026-03-12 وقت القراءة: 10 دق

Firebase Realtime Database هي قاعدة بيانات JSON سحابية في الزمن الفعلي أطلقتها Google في عام 2012 للتطبيقات المحمولة والويب. يتم تخزين جميع البيانات في شجرة JSON واحدة كبيرة ويتم مزامنتها بين العملاء المتصلين في الزمن الفعلي عبر اتصال WebSocket. وفقاً للتوثيق الرسمي Firebase, 2025، يمكن لـ Realtime Database خدمة ما يصل إلى 200,000 اتصال متزامن وتدعم ما يصل إلى 1000 عملية كتابة متزامنة في الثانية. لا تتطلب قاعدة البيانات بنية تحتية للخادم وتوفر SDK لنظام iOS و Android والويب ومنصات الخادم.

الملامح الرئيسية

  • Firebase Realtime DB هي قاعدة بيانات JSON سحابية مع مزامنة البيانات في الزمن الفعلي بين العملاء.
  • يتم تخزين البيانات كـ شجرة JSON واحدة، حيث يمكن الوصول إلى كل عقدة عبر مسار فريد.
  • يسمح وضع عدم الاتصال المدمج للتطبيق بالعمل بدون إنترنت ومزامنة التغييرات عند استعادة الاتصال.
  • تدعم ما يصل إلى 200,000 اتصال متزامن وما يصل إلى 1000 عملية كتابة في الثانية.
  • تتكامل مع Firebase Authentication وقواعد الأمان المخصصة للتحكم في الوصول إلى البيانات.

ما هو Firebase Realtime Database؟

Firebase Realtime Database هي قاعدة بيانات NoSQL سحابية تقوم بتخزين ومزامنة البيانات في الزمن الفعلي بين جميع العملاء المتصلين. أطلقت في عام 2012 باسم Firebase (قبل استحواذ Google عليها)، وأصبحت أول قاعدة بيانات سحابية في الزمن الفعلي لمطوري التطبيقات المحمولة. يتم تمثيل البيانات بتنسيق JSON وتنظيمها في شجرة هرمية، حيث لكل عقدة مسار فريد.

القيمة الأساسية لـ Realtime Database هي المزامنة المدمجة. عندما يغير تطبيق البيانات على أي جهاز، تتلقى جميع العملاء المتصلين الآخرين التحديث فوراً عبر اتصال دائم. هذا يلغي حاجة المطور لتنفيذ آلية المزامنة الخاصة به، أو خادم WebSocket، أو REST API لنقل البيانات بين العملاء.

توفر قاعدة البيانات SDK لجميع المنصات الرئيسية: Android (Java, Kotlin)، iOS (Swift, Objective-C)، الويب (JavaScript)، وبيئات الخادم عبر Admin SDK. وفقاً لـ Google، يتم استخدام Realtime Database في أكثر من 1.5 مليون مشروع نشط على Firebase في جميع أنحاء العالم. على الرغم من ظهور Firestore الأحدث، تظل Realtime Database خياراً شائعاً للمشاريع ذات هياكل البيانات البسيطة.

هيكل البيانات: شجرة JSON

على عكس قواعد البيانات العلائقية، لا تستخدم Realtime Database الجداول والصفوف. جميع البيانات هي شجرة JSON واحدة تشبه كائنات JavaScript المتداخلة. على سبيل المثال، لتخزين المستخدمين ورسائلهم، يتم إنشاء تسلسل هرمي: users/userId/name و messages/messageId/text. كل مسار في الشجرة هو سلسلة نصية، ويمكن الوصول إلى البيانات مباشرة عبر هذا المسار.

json
{
  "users": {
    "user1": {
      "name": "بتر بيتروف",
      "email": "ivan@example.com"
    },
    "user2": {
      "name": "ماريا سوكولوفا",
      "email": "maria@example.com"
    }
  },
  "messages": {
    "-Nabc123": {
      "text": "مرحباً!",
      "userId": "user1"
    }
  }
}

ميزة مهمة — التداخل العميق يؤثر على الأداء. عندما يقرأ التطبيق البيانات في مسار معين، فإنه يقوم بتحميل جميع العقد الفرعية لذلك المسار. لذلك، يوصى بتصميم هيكل البيانات بشكل مسطح قدر الإمكان، وتجنب التداخل لأكثر من 3-4 مستويات. لحل هذه المشكلة، يتم استخدام إلغاء التسوية (denormalization) — تكرار المعلومات في عقد شجرة مختلفة.

Realtime Database مقابل Firestore: متى تختار

غالباً ما تتم مقارنة Realtime Database و Firestore كقاعدتي بيانات سحابيتين في الزمن الفعلي من Google. يعتمد الاختيار بينهما على متطلبات المشروع المحددة: تعقيد الاستعلامات، الاتساق المطلوب، والحمل المتوقع. فهم نقاط القوة لكل قاعدة بيانات يساعد في اتخاذ القرار المعماري الصحيح.

الميزة الرئيسية لـ Realtime Database هي زمن الوصول المنخفض للمزامنة. نظراً لأن جميع البيانات مخزنة في شجرة JSON واحدة بدون طبقات تجريد إضافية، فإن المزامنة تتم بشكل أسرع من Firestore. للتطبيقات التي تكون فيها سرعة توصيل التحديثات حرجة (الدردشات، الألعاب عبر الإنترنت، أنظمة التحرير التعاوني)، قد تكون Realtime Database الخيار الأكثر ملاءمة.

متى تستخدم Realtime Database

Realtime Database مناسبة بشكل أفضل للسيناريوهات ذات هياكل البيانات البسيطة وتكرار التحديثات العالي. أمثلة نموذجية: الدردشات، الإعجابات في الزمن الفعلي، مؤشرات الكتابة، حالات تواجد المستخدمين. وهي أيضاً خيار جيد للنماذج الأولية والمشاريع ذات الميزانية المحدودة، حيث أن التسعير يعتمد على حجم البيانات وليس على عدد العمليات.

من ناحية أخرى، للتطبيقات ذات الاستعلامات المعقدة (التصفية حسب حقول متعددة، الترتيب، التجميع)، توفر Firestore إمكانيات أكثر قوة. تدعم Realtime Database التصفية فقط حسب معلمة واحدة ولا يمكنها ترتيب النتائج حسب حقول متعددة في وقت واحد. إذا كان المشروع يخطط لتحليلات بيانات معقدة على جانب العميل، سيكون Firestore خياراً أكثر عملية.

كيف تعمل المزامنة في Realtime Database

تستخدم Realtime Database اتصال WebSocket دائم للمزامنة ثنائية الاتجاه للبيانات. عندما يستدعي العميل setValue أو updateChildren على مسار معين، يتم إرسال البيانات إلى خادم Firebase عبر القناة المفتوحة. يطبق الخادم التغييرات ويوزع التحديثات على جميع العملاء المشتركين في غضون أجزاء من الثانية. يتم تحديد كل اتصال بمفتاح جلسة فريد.

تعمل آلية الاشتراك من خلال المستمعين (listeners). يمكن للمطور الاشتراك في تغييرات عقدة معينة (addListenerForSingleValueEvent) أو تلقي تحديثات مستمرة (addValueEventListener). في كل مرة تتغير فيها البيانات، يتم استدعاء callback onDataChange مع لقطة كاملة للبيانات في المسار المحدد. هذا يختلف عن Firestore، حيث يتم استلام المستندات المعدلة فقط — في Realtime Database، يتم دائماً تحميل جميع بيانات العقدة.

وضع عدم الاتصال وإدارة التعارضات

تدعم Realtime Database وضع عدم الاتصال على Android و iOS من خلال التخزين المؤقت على القرص. يحتفظ SDK بنسخة محلية من البيانات ويواصل معالجة عمليات الكتابة عند عدم وجود شبكة. عند استعادة الاتصال، يتم إرسال جميع التغييرات المتراكمة إلى الخادم. يتم استخدام استراتيجية آخر كتابة يفوز (last-write-wins) لحل التعارضات، ولكن يمكن للمطور تنفيذ منطق مخصص عبر ServerValue.TIMESTAMP لحل التصادمات.

kotlin
val database = FirebaseDatabase.getInstance()
val myRef = database.getReference("messages")

// كتابة البيانات
myRef.push().setValue(
    hashMapOf(
        "text" to "رسالة جديدة",
        "timestamp" to ServerValue.TIMESTAMP
    )
)

// قراءة بتحديثات مستمرة
myRef.addValueEventListener(object : ValueEventListener {
    override fun onDataChange(snapshot: DataSnapshot) {
        val data = snapshot.getValue()
        Log.d("TAG", "البيانات: $data")
    }

    override fun onCancelled(error: DatabaseError) {
        Log.w("TAG", "خطأ: ${error.message}")
    }
})

لتحسين حركة المرور والأداء، يوصى باستخدام child listeners بدلاً من value listeners عند تتبع تغييرات العقد الفرعية المحددة. يوفر ChildEventListener callbacks منفصلة لإضافة وتعديل وحذف ونقل العناصر الفرعية، مما يسمح بالتحكم الدقيق في تحديثات واجهة المستخدم وتجنب إعادة رسم جميع عناصر القائمة في كل تغيير بيانات.

قواعد الأمان والتحقق من صحة البيانات

تستخدم Realtime Database لغة قواعد تعريفية للتحكم في الوصول إلى البيانات. تصف القواعد من يمكنه قراءة وكتابة البيانات في كل مسار من شجرة JSON. يتم التحقق منها على خادم Firebase قبل كل طلب ولا تتطلب منطق خادم للتفويض. تدعم القواعد المتغيرات والكائنات المدمجة والوظائف لتكوين وصول مرن.

بشكل افتراضي، الوصول إلى قاعدة البيانات ممنوع لجميع المستخدمين. يفتح المطور الوصول تدريجياً باستخدام القاعدتين ".read" و ".write" على مستويات مختلفة من الشجرة. يمكن للشروط التحقق من المصادقة عبر متغير auth، ونوع الطلب (قراءة/كتابة)، والبيانات الموجودة عبر كائن data. بالإضافة إلى ذلك، تدعم القواعد التحقق من صحة البيانات المكتوبة عبر كائن newData.

js
{
  "rules": {
    "users": {
      "$uid": {
        // فقط المالك يستطيع قراءة بياناته
        ".read": "$uid === auth.uid",
        // فقط المالك يستطيع الكتابة
        ".write": "$uid === auth.uid",
        // التحقق من صحة الحقول عند الكتابة
        ".validate": "newData.hasChildren(['name', 'email'])"
      }
    },
    "messages": {
      // أي مستخدم موثق يستطيع القراءة
      ".read": "auth !== null",
      // فقط المستخدم الموثق يستطيع الكتابة
      ".write": "auth !== null",
      ".indexOn": ["timestamp"]
    }
  }
}

تدعم القواعد أيضاً فهرسة البيانات عبر التوجيه ".indexOn". بدونه، سيتم رفض الاستعلامات مع الترتيب (orderByChild) أو تنفيذها بشكل غير فعال. يتم تحديد المؤشرات لكل مسار حيث يتم إجراء الترتيب حسب حقل معين. القواعد متتالية: القواعد الأعمق تلغي القواعد الأم، وإذا لم يتم تعريف الوصول في مستوى ما، فإنه يعتبر مسموحاً أو ممنوعاً حسب القاعدة الأم.

أنواع البيانات والقيود

تدعم Realtime Database خمسة أنواع من البيانات: String، Number، Boolean، Map (كائن)، و List (مصفوفة). عمق التداخل محدود بـ 32 مستوى، والحد الأقصى لحجم عقدة واحدة يجب ألا يتجاوز 256 MB. للعمل بكفاءة مع قاعدة البيانات، يوصى بتصميم هيكل بيانات مسطح واستخدام إلغاء التسوية لتجنب الاستعلامات العميقة التي تحمل كميات كبيرة من البيانات.

مثال لاستخدام Realtime Database في Android

دعنا ننظر في مثال عملي لدمج Realtime Database في تطبيق Android لحالات المستخدم (متصل/غير متصل). سيعرض التطبيق قائمة بالمستخدمين مع حالتهم الحالية، محدثة في الزمن الفعلي. للعرض التوضيحي، يتم استخدام Firebase Authentication لتحديد هوية المستخدمين و coroutines للعمليات غير المتزامنة.

إعداد التبعيات والتهيئة

للبدء، أضف التبعية firebase-database-ktx إلى ملف build.gradle الخاص بوحدة التطبيق. يتم إدارة إصدار المكتبة عبر Firebase BoM لضمان توافق جميع المكونات. بعد إضافة التبعية، يجب تهيئة Firebase في فئة Application أو من خلال التهيئة البطيئة (lazy initialization) في ViewModel.

groovy
dependencies {
    implementation platform("com.google.firebase:firebase-bom:33.0.0")
    implementation "com.google.firebase:firebase-database-ktx"
    implementation "com.google.firebase:firebase-auth-ktx"
}

بعد التهيئة، يتم إنشاء مستودع (repository) للعمل مع المستخدمين. يتم تمثيل كل مستخدم بعقدة في الشجرة /users/{uid} مع حقول name و email و status. لتتبع الحالة، يتم استخدام onDisconnect — آلية خاصة من Firebase تقوم تلقائياً بتنفيذ عملية كتابة عند انقطاع اتصال العميل. هذا يضمن تغيير حالة المستخدم إلى "offline" عند إغلاق التطبيق أو فقدان الشبكة دون الحاجة إلى كود إضافي على العميل.

kotlin
class PresenceRepository {
    private val database = FirebaseDatabase.getInstance()
    private val auth = FirebaseAuth.getInstance()
    private val presenceRef = database
        .getReference("presence")

    fun trackPresence() {
        val uid = auth.currentUser?.uid ?: return
        val userRef = presenceRef.child(uid)

        userRef.onDisconnect().setValue("offline")
        userRef.setValue("online")
    }

    fun getPresenceStream(): Flow<Map<String, String>> =
        presenceRef.snapshotFlow()
            .map { snapshot ->
                (snapshot.value as? Map<*, *>)
                    ?.mapKeys { it.key.toString() }
                    ?.mapValues { it.value.toString() }
                    ?: emptyMap()
            }
}

العنصر الأساسي في المثال هو onDisconnect. تسمح هذه الآلية بتعيين عملية كتابة سيتم تنفيذها على الخادم عند انقطاع اتصال العميل. في هذه الحالة، عند فصل المستخدم، يتم تعيين حالته تلقائياً إلى "offline" دون الحاجة لمعالجة حدث إغلاق التطبيق. إذا تعطل التطبيق، سيقوم Firebase نفسه بتنفيذ عملية onDisconnect، وسيرى المستخدمون الآخرون الحالة الصحيحة.

الأسئلة الشائعة

ما الفرق بين Firebase Realtime Database و Firestore؟

Realtime Database تخزن البيانات في شجرة JSON واحدة وتوفر زمن وصول أقل للمزامنة. تستخدم Firestore مجموعات المستندات، وتدعم الاستعلامات المعقدة والاتساق القوي. Realtime Database أفضل للدردشات البسيطة والحالات، و Firestore أفضل للتطبيقات ذات هياكل البيانات المعقدة والتحليلات.

ما هو الحد الأقصى لحجم البيانات في Realtime Database؟

الحد الأقصى لحجم عقدة واحدة في Realtime Database هو 256 MB. عمق التداخل محدود بـ 32 مستوى. لمشروع Firebase واحد، يمكن إنشاء قواعد بيانات Realtime Database متعددة (حتى 5 في خطة Spark وحتى 100 في خطة Blaze)، مما يسمح بتوزيع البيانات عبر مثيلات مختلفة.

كيف تعمل المصادقة في Realtime Database؟

Realtime Database تتكامل مع Firebase Authentication. متغير auth الذي يحتوي على uid للمستخدم الموثق متاح في قواعد الأمان. يمكن للمطور تقييد الوصول على مستوى العقد الفردية لشجرة JSON عن طريق التحقق من uid مالك البيانات. المستخدمون المجهولون وغير الموثقين لديهم auth = null.

هل تدعم Realtime Database المعاملات (transactions)؟

نعم، تدعم Realtime Database المعاملات عبر طريقة runTransaction. تضمن المعاملة ذرية عملية القراءة-التعديل-الكتابة لعقدة واحدة. عند حدوث تغييرات متزامنة، يتم إعادة محاولة المعاملة بالبيانات الحالية. هذا مفيد للعدادات والتقييمات والسيناريوهات الأخرى حيث يكون اتساق البيانات مهماً.

هل يمكن استخدام Realtime Database بدون إنترنت؟

نعم، تدعم Realtime Database وضع عدم الاتصال على Android و iOS. يقوم SDK بتخزين البيانات محلياً ويستمر في معالجة عمليات الكتابة عند عدم وجود شبكة. عند استعادة الاتصال، تتم مزامنة جميع التغييرات المتراكمة مع الخادم. لتمكين وضع عدم الاتصال، استخدم طريقة keepSynced(true) على العقدة المطلوبة.

الخلاصة

  • Firebase Realtime Database هي قاعدة بيانات JSON سحابية مع مزامنة في الزمن الفعلي بين العملاء عبر WebSocket.
  • يتم تخزين البيانات في شجرة JSON بهيكل هرمي والوصول عبر مسارات فريدة لكل عقدة.
  • وضع عدم الاتصال المدمج مع التخزين المؤقت على القرص يسمح للتطبيق بالعمل بدون اتصال بالإنترنت.
  • آلية onDisconnect تنفذ العمليات تلقائياً عند فقدان الاتصال — مثالية لحالات التواجد.
  • قواعد الأمان و التحقق من صحة البيانات يتم تكوينها بطريقة تعريفية بدون كود خادم.
  • التسعير يعتمد على حجم البيانات، وليس على عدد العمليات، مما يجعله فعالاً من حيث التكلفة للتطبيقات ذات التحديثات المتكررة.
  • للمشاريع ذات هياكل البيانات البسيطة ومتطلبات زمن الوصول الأدنى، تظل Realtime Database الخيار الأمثل.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا