دليل عملي إلى Firebase Cloud Firestore: شرح سريع لقاعدة البيانات للمبتدئين

دقائق القراءة: 7
واجهة توضيحية لشرح 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: مستندات داخل كل مجموعة، وتُخزن بداخلها الحقول والقيم.

هذا النمط يمنح المطور مرونة كبيرة في تصميم البيانات، خاصة عند بناء واجهات تفاعلية وتطبيقات حديثة.

بنية Cloud Firestore المعتمدة على Collections وDocuments داخل قاعدة بيانات NoSQL

لماذا يعتبر 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

  1. انتقل إلى موقع Firebase.
  2. أنشئ حسابًا جديدًا أو سجّل الدخول إن كان لديك حساب مسبق.
  3. اضغط على Go to console أو Get Started.
  4. اختر Add project.
  5. أدخل اسم المشروع وأكمل خطوات الإنشاء.

الخطوات اللاحقة مباشرة وبسيطة، وعند الانتهاء سيكون مشروعك جاهزًا للربط مع تطبيق الويب.

تثبيت 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 وخيار تهيئة تطبيق الويب باستخدام إعدادات Firestore

تهيئة 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.

عرض البيانات المخزنة داخل مجموعة userInfo في Firebase Cloud Firestore

كيفية قراءة البيانات من 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 خيارًا ممتازًا لبدء مشاريع سريعة وقابلة للنمو، بشرط الانتباه إلى قواعد الأمان، وتنظيم البيانات، وإنشاء الفهارس عند الحاجة إلى استعلامات أكثر تقدمًا.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *