Firebase Firestore هي قاعدة بيانات مستندات NoSQL مرنة من Google مع مزامنة تلقائية في الوقت الفعلي للتطبيقات المحمولة والويب. يتم تخزين البيانات كمستندات ومجموعات، تحتوي كل منها على مجموعة من الحقول ذات بنية عشوائية. وفقًا لـ Google، 2026، يدعم Firestore النسخ المتماثل متعدد المناطق مع الاسترداد التلقائي عند الفشل. يرسل SDK التغييرات إلى الخادم عبر اتصال WebSocket بزمن استجابة أقل من 100 مللي ثانية.
الرئيسية
Firebase Firestore هي قاعدة بيانات NoSQL سحابية أطلقتها Google في 2019 كخليفة لـ Realtime Database. تم بناء Firestore على البنية التحتية لـ Google Cloud Spanner و Google Cloud Datastore، مما يوفر تناسقًا قويًا للبيانات ضمن معاملة واحدة ونسخًا متماثلًا تلقائيًا متعدد المناطق. يدعم SDK أنظمة Android و iOS و Web (JavaScript) و Flutter و Kotlin Multiplatform و Unity.
تم الإعلان عن Firestore في Google I/O 2017 باسم «Cloud Firestore» — وهو حل يعالج القيود الرئيسية لـ Realtime Database: عدم دعم الاستعلامات المعقدة، وعدم القدرة على توسيع البيانات عبر عقد متعددة، والتناسق الضعيف. وفقًا لـ Google (2026)، يعالج Firestore أكثر من تريليون طلب يوميًا وهو قاعدة البيانات الافتراضية لـ 80% من مشاريع Firebase الجديدة. ومع ذلك، تظل Realtime Database مناسبة لسيناريوهات زمن الاستجابة المنخفض جدًا (الألعاب، التحرير التعاوني) بفضل بنيتها JSON المباشرة.
يتم تقديم Firestore بنموذج الدفع حسب الاستخدام مع حد مجاني سخي في خطة Spark: 1 جيجابايت من التخزين، 10 جيجابايت من حركة مرور الشبكة شهريًا، 50 ألف عملية قراءة، 20 ألف عملية كتابة و 20 ألف عملية حذف يوميًا. في خطة Blaze، كل ما سبق مجاني، ويتم فرض رسوم على التجاوزات: 0.06 دولار لكل 100 ألف عملية قراءة، 0.18 دولار لكل 100 ألف عملية كتابة. وفقًا لـ Google (2026)، يبقى 90% من المشاريع ضمن الحد المجاني.
نموذج البيانات لـ Firestore منظم هرميًا: الجذر يحتوي على مجموعات، كل مجموعة تحتوي على مستندات، كل مستند يحتوي على حقول (أنواع بدائية، مصفوفات، Map) ومجموعات متداخلة (مجموعات فرعية). عمق تداخل المجموعات غير محدود، لكن المستند لا يمكن أن يحتوي على مستند آخر مباشرة — فقط من خلال مرجع (نوع Reference).
المجموعة هي حاوية من المستندات بمعرفات يتم إنشاؤها تلقائيًا أو يحددها المستخدم. كل مستند هو كائن يشبه JSON بحجم يصل إلى 1 MiB. يمكن أن تكون حقول المستند سلاسل نصية أو أرقامًا أو قيمًا منطقية أو مصفوفات أو Map أو طوابع زمنية (Timestamp) أو نقاط جغرافية (GeoPoint) أو مراجع لمستندات أخرى (Reference). حجم المستند محدود بـ 1 MiB بما في ذلك أسماء جميع الحقول.
| نوع حقل Firestore | مثال | مفهرس |
|---|---|---|
| String | «user@example.com» | نعم |
| Number | 42, 3.14 | نعم |
| Boolean | true, false | نعم |
| Array | [1, 2, 3] | يحتوي فقط |
| Map | {«nested»: «value»} | نعم (حسب المفاتيح) |
| Timestamp | 2026-07-03T12:00:00Z | نعم |
| Reference | users/user123 | نعم |
يدعم Firestore المعاملات الذرية على مستوى قاعدة البيانات. يمكن للمعاملة قراءة وكتابة مستندات متعددة — Commit يطبق جميع التغييرات بشكل ذري أو لا شيء على الإطلاق. الحد الأقصى 500 عملية لكل معاملة، مهلة 60 ثانية. الكتابة الدفعية (batch write) هي عملية كتابة ذرية غير معاملاتية بدون مرحلة قراءة. المعاملات ضرورية للعمليات المالية وحجوزات المقاعد وإدارة المخزون.
الاختيار بين Firestore و Realtime Database يعتمد على متطلبات المشروع. كلتا قاعدتي البيانات جزء من نظام Firebase البيئي، وتوفران مزامنة في الوقت الفعلي، ومتاحتان على جميع المنصات، لكنهما تختلفان جوهريًا في نموذج البيانات والتوسع والتسعير.
Realtime Database تخزن البيانات في شجرة JSON واحدة، وهو مناسب للهياكل البسيطة لكنه يصعّب التوسع عند التداخل لأكثر من 3 مستويات. يستخدم Firestore نموذج المجموعات والمستندات مع التقسيم التلقائي، مما يسمح بالتوسع لملايين المستندات دون تدهور الأداء. وفقًا لـ Google (2026)، يدعم Firestore ما يصل إلى 10 آلاف اتصال متزامن لمجموعة واحدة دون فقدان السرعة، بينما تدعم Realtime Database ما يصل إلى 200 ألف اتصال لمثيل واحد.
Realtime Database تُفوتر بناءً على حجم البيانات المنقولة (البايتات التي تم تنزيلها) وعدد الاتصالات المتزامنة. Firestore يُفوتر بعدد العمليات (قراءة، كتابة، حذف). للتطبيقات ذات التحديثات الصغيرة المتكررة (الدردشة، الإشعارات)، يكون Firestore عادةً أكثر فعالية من حيث التكلفة — لكل عملية كتابة سعر ثابت بغض النظر عن حجم البيانات. للتطبيقات ذات القراءات النادرة لكميات كبيرة من البيانات، قد تكون Realtime Database أرخص.
توصية Google (2026): استخدم Firestore كقاعدة بيانات افتراضية للمشاريع الجديدة، و Realtime Database للألعاب والتطبيقات حيث يكون زمن الاستجابة الأدنى (أقل من 50 مللي ثانية) وهيكل البيانات المسطح أمرًا بالغ الأهمية. يمكن لكلتا قاعدتي البيانات العمل في وقت واحد في نفس المشروع.
استعلامات Firestore تُنفذ على المجموعات أو مجموعات المجموعات مع التصفية والترتيب والحدود. على عكس Realtime Database، حيث يجتاز كل استعلام شجرة JSON بأكملها مع تصفية من جانب العميل، ينفذ Firestore جميع الاستعلامات على الخادم باستخدام فهارس تم إنشاؤها مسبقًا. يضمن هذا أن تعقيد الاستعلام يعتمد فقط على حجم النتيجة، وليس على حجم المجموعة.
يدعم Firestore التصفية بحقل واحد أو多个 (المساواة، النطاق، in، array-contains، array-contains-any)، والترتيب تصاعديًا وتنازليًا، والحدود، والمؤشرات للترقيم. القيود: الاستعلامات المركبة مع التصفية بحقول مختلفة (where price > 10 AND where category == «books») تتطلب فهرسًا مركبًا؛ استعلامات OR محظورة (استخدم in و array-contains-any بدلاً من ذلك)، ولا يُسمح باستعلامات عدم المساواة على حقول مختلفة.
data class Product(
val name: String = "",
val category: String = "",
val price: Double = 0.0,
val inStock: Boolean = false
)
suspend fun FirestoreRepository.queryProducts(): List<Product> {
return firestore
.collection("products")
.whereEqualTo("category", "electronics")
.whereGreaterThanOrEqualTo("price", 100.0)
.whereLessThan("price", 500.0)
.orderBy("price")
.limit(20)
.get()
.await()
.toObjects(Product::class.java)
}
يقوم Firestore تلقائيًا بإنشاء فهارس للحقول الفردية — استعلامات الحقل الواحد تعمل دون أي تكوين. للاستعلامات ذات حقلين أو أكثر (تصفية + ترتيب)، يلزم وجود فهارس مركبة. عند إرسال استعلام لأول مرة، يُرجع Firestore خطأً مع رابط لوحدة التحكم حيث يمكن إنشاء الفهرس بنقرة واحدة. الحد الأقصى 200 فهرس مركب لكل قاعدة بيانات. يمكن تصدير الفهارس واستيرادها عبر Firebase CLI.
توصيل Firestore بتطبيق Android يتم بشكل قياسي عبر Firebase BOM. بعد إضافة التبعية firebase-firestore-ktx، يكون كائن FirebaseFirestore متاحًا عبر getInstance() — بدون مفاتيح أو رموز إضافية. يستخدم Firestore نفس مشروع Firebase الذي تستخدمه الخدمات الأخرى.
dependencies {
implementation(platform("com.google.firebase:firebase-bom:33.1.0"))
implementation("com.google.firebase:firebase-firestore-ktx")
}
// التهيئة
val db = FirebaseFirestore.getInstance()
يوفر Firestore وضعين للقراءة: لمرة واحدة (get) وفي الوقت الفعلي (addSnapshotListener). القراءة لمرة واحدة تسترجع المستند مرة واحدة — مفيد للإعدادات والتكوين. المستمع يشترك في التغييرات — أي تحديث للمستند يسلم تلقائيًا البيانات المحدثة لجميع العملاء المتصلين في الوقت الفعلي. set() تنشئ أو تستبدل المستند، update() تعدل فقط الحقول المحددة دون استبدال المستند بأكمله.
وفقًا لـ Google (2026)، تستهلك التطبيقات متوسطة الحجم (100 ألف مستخدم نشط يوميًا) مع Firestore في الوقت الفعلي حوالي 5-10 جيجابايت من حركة المرور الصادرة شهريًا. استخدام التخزين المؤقت دون اتصال (Persistence Cache) يقلل التنزيلات المتكررة بنسبة 60-70%، حيث يقوم SDK بتحميل المستندات المتغيرة فقط عند استعادة الاتصال.
Persistence Cache هي آلية مدمجة في Firestore للعمل دون اتصال بالإنترنت. يقوم SDK تلقائيًا بتخزين جميع المستندات المقروءة مؤقتًا على الجهاز (حتى 500 MiB على Android). عند فقدان الاتصال، تستمر القراءة من التخزين المؤقت، وتوضع عمليات الكتابة في قائمة انتظار. عند استعادة الاتصال، يتم إرسال جميع العمليات المعلقة إلى الخادم، وتتم مزامنة التخزين المؤقت مع الخادم. للتحكم في التعارضات، استخدم snapshot-metadata.hasPendingWrites و setOptions(ServerTimestampBehavior).
Security Rules هي لغة تحكم في الوصول تصريحية لـ Firestore تُنفذ على خادم Google قبل كل عملية قراءة أو كتابة. لا تتطلب القواعد كودًا من جانب الخادم — تُكتب في وحدة تحكم Firebase أو عبر Firebase CLI وتُدار إصداراتها عبر Git. يتم التحقق من كل عملية وفقًا للقواعد، ويؤدي الانتهاك إلى إرجاع خطأ PERMISSION_DENIED.
تتكون Firestore Security Rules من كتل match وتعبيرات allow. يحدد match المسار إلى مجموعة أو مستند، ويحدد allow العمليات المسموح بها (read, write, create, update, delete) وشرطًا — تعبيرًا يشبه JavaScript يُرجع قيمة منطقية. يمكن للقواعد التحقق من المصادقة (request.auth) وبيانات الطلب (request.resource.data) والبيانات الموجودة (resource.data) والوقت (request.time) والمسار (request.path).
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read: if request.auth != null;
allow write: if request.auth.uid == userId;
}
match /products/{productId} {
allow read: if true;
allow create: if request.auth.token.role == "admin";
allow update: if resource.data.authorId == request.auth.uid;
}
}
}
تدعم Security Rules التحقق من صحة الأنواع والقيم على جانب الخادم. يمكنك منع الكتابة إذا كان السعر سالبًا أو الاسم فارغًا. يتم إجراء جميع التحققات على خادم Google قبل الكتابة — وهذا يضمن اتساق البيانات بغض النظر عن العميل (Android، iOS، Web، Admin SDK). القواعد لا تحمي من Admin SDK الخبيث — فهو يتجاوز القواعد حسب التصميم. للحماية الكاملة، استخدم Transaction Functions و Firebase Extensions.
الأسئلة المتداولة
Firestore يستخدم نموذج مستندات مع فهارس واستعلامات معقدة. Realtime Database تخزن البيانات في شجرة JSON وتوفر زمن استجابة أقل. يُوصى باستخدام Firestore للمشاريع الجديدة.
Firestore يقسم البيانات تلقائيًا عبر المجموعات — لا حاجة لتكوين النسخ المتماثل أو التقسيم. تتعامل قاعدة البيانات مع ملايين المستندات في مجموعة واحدة وآلاف الاتصالات المتزامنة دون تدهور.
نعم، استخدم Firebase Console — ميزة «Export to Firestore» تحول بنية JSON لـ Realtime Database إلى مجموعات ومستندات Firestore ببضع نقرات. تصبح العقد المتداخلة مجموعات متداخلة.
Last write wins — افتراضيًا، يستخدم Firestore سياسة «آخر كتابة تفوز» لحل التعارضات أثناء الكتابات المتزامنة. للمعالجة المخصصة، استخدم المعاملات مع إعادة القراءة.
الحد المجاني لخطة Spark: 1 جيجابايت من التخزين، 50 ألف عملية قراءة و 20 ألف عملية كتابة يوميًا. هذا كافٍ للنماذج الأولية والتطبيقات ذات الحركة المنخفضة.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا