دليل عملي إلى Firebase Cloud Firestore: شرح سريع لقاعدة البيانات للمبتدئين
يُعد Firebase Cloud Firestore واحدًا من أهم حلول قواعد البيانات الحديثة التي تقدمها Firebase لبناء تطبيقات الويب والهواتف بسرعة وكفاءة. يتيح هذا المنتج تخزين البيانات ومزامنتها واسترجاعها من خلال قاعدة بيانات تعتمد على المستندات document-based database، وهو ما يجعله مناسبًا جدًا للتطبيقات التي تحتاج إلى مرونة عالية وتوسع سلس.
في هذا الدليل العملي، سنتعرف إلى أساسيات Cloud Firestore، وكيفية إعداده داخل مشروع ويب، ثم سننتقل إلى إضافة البيانات وقراءتها وتنفيذ الاستعلامات عليها، مع أمثلة واضحة باستخدام HTML وJavaScript.
ما هو Firebase Cloud Firestore؟
Cloud Firestore هو نظام قاعدة بيانات NoSQL سحابي من Firebase وGoogle Cloud، صُمم ليكون مرنًا وقابلًا للتوسع وملائمًا لتطوير تطبيقات mobile وweb وserver.
بعكس قواعد البيانات التقليدية التي تخزن المعلومات داخل جداول وصفوف وأعمدة، يعتمد Firestore على هيكل مكوّن من:
- Collections: مجموعات رئيسية لتنظيم البيانات.
- Documents: مستندات داخل كل مجموعة، وتُخزن بداخلها الحقول والقيم.
هذا النمط يمنح المطور مرونة كبيرة في تصميم البيانات، خاصة عند بناء واجهات تفاعلية وتطبيقات حديثة.

لماذا يعتبر Firestore خيارًا قويًا لتطبيقات الويب؟
يوفر Firestore مزايا عملية تجعله مناسبًا للمشاريع الصغيرة والمتوسطة وحتى الأنظمة القابلة للنمو:
- سهولة الإعداد دون الحاجة إلى إدارة خادم قاعدة بيانات يدويًا.
- إمكانية التوسع تلقائيًا مع نمو التطبيق.
- تكامل مباشر مع منظومة Firebase.
- دعم ممتاز لمطوري front-end الذين يرغبون في بناء تطبيقات full stack بسرعة.
- إمكانية فرض قواعد أمان Security Rules لحماية البيانات.
إنشاء مشروع محلي بسيط للعمل على Firestore
سنستخدم في هذا الشرح ملف HTML وملف JavaScript فقط، لأن التركيز هنا منصب على التعامل مع البيانات وليس على التصميم.
يمكنك إنشاء ملف HTML أساسي بهذا الشكل:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Firestore</title>
</head>
<body>
<script src="app.js"></script>
</body>
</html>
بعد ذلك، أنشئ ملف JavaScript باسم app.js أو أي اسم آخر تفضله.
كيفية إعداد المشروع داخل Firebase
- انتقل إلى موقع Firebase.
- أنشئ حسابًا جديدًا أو سجّل الدخول إن كان لديك حساب مسبق.
- اضغط على Go to console أو Get Started.
- اختر Add project.
- أدخل اسم المشروع وأكمل خطوات الإنشاء.
الخطوات اللاحقة مباشرة وبسيطة، وعند الانتهاء سيكون مشروعك جاهزًا للربط مع تطبيق الويب.
تثبيت Firebase وتهيئته داخل المشروع
تثبيت الحزمة عبر npm
إذا كنت تستخدم بيئة تطوير تعتمد على npm، فابدأ بتثبيت Firebase عبر الأمر التالي:
npm install firebase
إضافة مكتبات Firebase إلى صفحة HTML
للاستخدام المباشر عبر الصفحة، أضف ملفات Firebase داخل وسم head:
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-firestore.js"></script>
<title>Firestore</title>
</head>
الملف الأول مسؤول عن تحميل مكتبة Firebase الأساسية، بينما الثاني يفعّل خصائص Firestore.
إنشاء قاعدة Firestore من لوحة Firebase
من داخل لوحة التحكم الخاصة بالمشروع:
- انتقل إلى Firestore Database.
- ابدأ بإنشاء قاعدة البيانات.
- اختر Test Mode أثناء التطوير لتسهيل تنفيذ الطلبات دون مصادقة.
لكن من المهم جدًا تعديل Security Rules لاحقًا قبل نشر المشروع، لأن وضع الاختبار ليس مناسبًا للإنتاج.

تهيئة Firebase داخل مشروع الويب
من صفحة Project Overview اضغط على أيقونة الويب </>، ثم انسخ القيم المطلوبة مثل apiKey وauthDomain وprojectId.
بعد ذلك، استخدم الشيفرة التالية لتهيئة المشروع:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-firestore.js"></script>
<title>Firestore</title>
</head>
<body>
<script>
firebase.initializeApp({
apiKey: "### FIREBASE API KEY ###",
authDomain: "### FIREBASE AUTH DOMAIN ###",
projectId: "### CLOUD FIRESTORE PROJECT ID ###",
});
const db = firebase.firestore();
</script>
<script src="app.js"></script>
</body>
</html>
احرص على استبدال القيم الافتراضية بالقيم الحقيقية التي حصلت عليها من Firebase.
إضافة البيانات إلى Firestore من الواجهة الأمامية
يمكنك إدخال البيانات يدويًا من لوحة Firebase، لكن في التطبيقات الحقيقية من الأفضل الإضافة مباشرة من الواجهة الأمامية.
لنبدأ بإضافة عناصر الإدخال التالية إلى الصفحة:
<div class="content">
<input type="text" id="username" placeholder="username">
<textarea name="" id="about" placeholder="about"></textarea>
<button id="btn">ADD</button>
</div>
التعامل مع عناصر النموذج عبر JavaScript
const username = document.getElementById('username');
const about = document.getElementById('about');
const btn = document.getElementById('btn');
حفظ البيانات داخل Collection جديدة
btn.addEventListener('click', () => {
db.collection('userInfo').add({
username: username.value,
bio: about.value
});
username.value = '';
about.value = '';
})
عند تنفيذ هذا الكود، سيبحث Firestore عن مجموعة باسم userInfo. وإذا لم تكن موجودة فسيتم إنشاؤها تلقائيًا. كما سيولّد معرفًا id لكل مستند جديد بشكل آلي إذا لم تحدده بنفسك.
تستقبل الدالة .add() كائنًا يحتوي على البيانات المراد حفظها بصيغة key/value، مثل username وbio.

كيفية قراءة البيانات من Firestore وعرضها في الصفحة
بعد تخزين البيانات، نحتاج عادة إلى استرجاعها وعرضها للمستخدم. يمكننا البدء بإضافة عنصر ul داخل الصفحة ليكون حاوية للنتائج:
<body>
<div class="content">
<ul id="lists"></ul>
</div>
</body>
الآن ننشئ العناصر المطلوبة ديناميكيًا باستخدام JavaScript:
const lists = document.getElementById("lists");
db.collection("userInfo")
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
let li = document.createElement("li");
let username = document.createElement("h4");
let bio = document.createElement("p");
username.textContent = doc.data().username;
bio.textContent = doc.data().bio;
li.appendChild(username);
li.appendChild(bio);
lists.appendChild(li);
});
})
.catch((error) => {
console.log("Error getting documents: ", error);
});
تقوم الدالة .get() بجلب البيانات من المجموعة، ثم تُعيد Promise. وعند نجاح الطلب نحصل على querySnapshot الذي يمثل الحالة الحالية للنتائج.
بعد ذلك نستخدم forEach() للمرور على كل مستند، ثم نستخرج القيم بواسطة doc.data() ونضيفها إلى عناصر الصفحة.
تنفيذ الاستعلامات على البيانات في Firestore
الاستعلامات Queries تتيح لك تصفية النتائج وفق شروط محددة، وهو أمر مهم عند بناء صفحات البحث أو لوحات التحكم أو أنظمة التصنيف.
إليك مثالًا بسيطًا على استعلام يعرض المستندات التي يكون فيها username مساويًا لقيمة معينة:
db.collection("userInfo")
.where('username', '==', 'Ihechikara')
.get()
.then((querySnapshot) => {
querySnapshot.forEach(doc => {
console.log(doc.data())
})
})
.catch((error) => {
console.log("Error getting documents: ", error);
});
تستقبل الدالة where() ثلاثة معاملات:
- اسم الحقل.
- عامل المقارنة.
- القيمة المراد المقارنة بها.
بمعنى آخر: اذهب إلى مجموعة userInfo وأعد فقط المستخدم الذي يطابق اسمه القيمة المحددة.
أشهر معاملات المقارنة المتاحة
| المعامل | المعنى |
|---|---|
| < | أصغر من |
| <= | أصغر من أو يساوي |
| > | أكبر من |
| >= | أكبر من أو يساوي |
| == | يساوي |
| != | لا يساوي |
| array-contains | تحتوي المصفوفة على قيمة |
| array-contains-any | تحتوي المصفوفة على أي قيمة من عدة قيم |
| in | القيمة ضمن مجموعة محددة |
| not-in | القيمة ليست ضمن مجموعة محددة |
ترتيب البيانات وتحديد عدد النتائج
من الميزات المهمة في Firestore القدرة على ترتيب النتائج أو تقليل عددها، وهو ما يفيد في بناء القوائم والصفحات السريعة والواجهات التي تعرض بيانات محدودة.
ترتيب البيانات تصاعديًا
db.collection("userInfo")
.orderBy('username')
.get()
.then((querySnapshot) => {
querySnapshot.forEach(doc => {
console.log(doc.data())
})
})
.catch((error) => {
console.log("Error getting documents: ", error);
});
يعيد هذا الاستعلام البيانات مرتبة أبجديًا بناءً على username.
ترتيب البيانات تنازليًا
db.collection("userInfo")
.orderBy('username', 'desc')
.get()
.then((querySnapshot) => {
querySnapshot.forEach(doc => {
console.log(doc.data())
})
})
.catch((error) => {
console.log("Error getting documents: ", error);
});
دمج where مع orderBy
يمكنك دمج أكثر من دالة داخل استعلام واحد للحصول على نتائج أدق:
db.collection("userInfo")
.where("bio", "==", "Web Developer")
.orderBy('username')
.get()
.then((querySnapshot) => {
querySnapshot.forEach(doc => {
console.log(doc.data())
})
})
.catch((error) => {
console.log("Error getting documents: ", error);
});
إذا ظهر لك خطأ يفيد بأن الاستعلام يحتاج إلى index، فاضغط على الرابط الذي يظهر في رسالة الخطأ داخل وحدة التحكم، وسيتم توجيهك لإنشاء الفهرس المطلوب من Firebase Console.
تحديد عدد النتائج باستخدام limit
db.collection("userInfo")
.limit(1)
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
console.log(doc.data());
});
})
.catch((error) => {
console.log("Error getting documents: ", error);
});
تستقبل الدالة limit() رقمًا واحدًا يحدد عدد المستندات المراد إرجاعها. في المثال السابق، سيتم إرجاع مستند واحد فقط.
نصائح مهمة عند استخدام Firestore في المشاريع الحقيقية
- لا تعتمد على Test Mode في بيئة الإنتاج.
- احرص على كتابة Security Rules واضحة لحماية البيانات.
- صمم هيكل Collections وDocuments بعناية قبل التوسع.
- استخدم الفهارس Indexes عند تنفيذ الاستعلامات المركبة لتحسين الأداء.
- تأكد من التحقق من الإدخال Validation في الواجهة الأمامية والخلفية عند الحاجة.
الخلاصة التقنية
يمنحك Firebase Cloud Firestore طريقة سريعة وعملية لبناء قاعدة بيانات حديثة لتطبيقات الويب دون الدخول في تعقيدات إدارة الخوادم. وبفضل أسلوبه المعتمد على Collections وDocuments، يصبح التعامل مع البيانات أكثر مرونة، خاصة لمطوري JavaScript وfront-end. تقنيًا، يُعد Firestore خيارًا ممتازًا لبدء مشاريع سريعة وقابلة للنمو، بشرط الانتباه إلى قواعد الأمان، وتنظيم البيانات، وإنشاء الفهارس عند الحاجة إلى استعلامات أكثر تقدمًا.