1. نظرة عامة
في هذا الدرس التطبيقي حول الترميز، ستتعرّف على بعض أساسيات Firebase لإنشاء تطبيقات ويب تفاعلية. ستنشئ تطبيقًا للرد على الدعوة وسجلّ الزوّار للمحادثة باستخدام العديد من منتجات Firebase.

ما ستتعلمه
- مصادقة المستخدمين باستخدام "مصادقة Firebase" وFirebaseUI
- مزامنة البيانات باستخدام Cloud Firestore
- اكتب "قواعد أمان Firebase" لتأمين قاعدة بيانات.
المتطلبات
- متصفّح من اختيارك، مثل Chrome
- الوصول إلى stackblitz.com (لا يلزم إنشاء حساب أو تسجيل الدخول)
- حساب Google، مثل حساب Gmail ننصحك باستخدام حساب البريد الإلكتروني الذي تستخدمه حاليًا لحسابك على GitHub. يتيح لك ذلك استخدام ميزات متقدّمة في StackBlitz.
- الرمز النموذجي الخاص بالتجربة العملية راجِع الخطوة التالية لمعرفة كيفية الحصول على الرمز.
2. الحصول على الرمز الأولي
في هذا الدرس التطبيقي حول الترميز، ستنشئ تطبيقًا باستخدام StackBlitz، وهو محرّر على الإنترنت يتضمّن العديد من مهام سير عمل Firebase. لا يتطلّب Stackblitz تثبيت أي برامج أو إنشاء حساب خاص على Stackblitz.
يتيح لك StackBlitz مشاركة المشاريع مع الآخرين. يمكن للمستخدمين الآخرين الذين لديهم عنوان URL الخاص بمشروعك على StackBlitz الاطّلاع على الرمز البرمجي وإنشاء نسخة من مشروعك، ولكن لا يمكنهم تعديل مشروعك على StackBlitz.
- انتقِل إلى عنوان URL هذا للحصول على رمز البداية: https://stackblitz.com/edit/firebase-gtk-web-start
- في أعلى صفحة StackBlitz، انقر على Fork:

تتوفّر لديك الآن نسخة من رمز البداية كمشروع StackBlitz خاص بك، وله اسم فريد، بالإضافة إلى عنوان URL فريد. يتم حفظ جميع ملفاتك وتغييراتك في مشروع StackBlitz هذا.
3- تعديل معلومات الحدث
توفّر المواد الأولية لهذا الدرس التطبيقي حول الترميز بعض البنية لتطبيق الويب، بما في ذلك بعض أوراق الأنماط وحاويتين HTML للتطبيق. وفي وقت لاحق من هذا الدرس التطبيقي حول الترميز، ستربط هاتين الحاويتين بـ Firebase.
للبدء، دعونا نتعرّف أكثر على واجهة StackBlitz.
- في StackBlitz، افتح الملف
index.html. - ابحث عن
event-details-containerوdescription-container، ثم جرِّب تعديل بعض تفاصيل الحدث.
أثناء تعديل النص، ستعرض عملية إعادة تحميل الصفحة التلقائية في StackBlitz تفاصيل الحدث الجديدة. رائع، أليس كذلك؟
<!-- ... -->
<div id="app">
<img src="..." />
<section id="event-details-container">
<h1>Firebase Meetup</h1>
<p><i class="material-icons">calendar_today</i> October 30</p>
<p><i class="material-icons">location_city</i> San Francisco</p>
</section>
<hr>
<section id="firebaseui-auth-container"></section>
<section id="description-container">
<h2>What we'll be doing</h2>
<p>Join us for a day full of Firebase Workshops and Pizza!</p>
</section>
</div>
<!-- ... -->
يجب أن تبدو معاينة تطبيقك على النحو التالي:
معاينة التطبيق

4. إنشاء مشروع Firebase وإعداده
يُعدّ عرض معلومات الحدث أمرًا رائعًا للضيوف، ولكن مجرد عرض الأحداث ليس مفيدًا لأي شخص. لنضِف بعض الوظائف الديناميكية إلى هذا التطبيق. ولإجراء ذلك، عليك ربط Firebase بتطبيقك. للبدء في استخدام Firebase، عليك إنشاء مشروع Firebase وإعداده.
إنشاء مشروع Firebase
- سجِّل الدخول إلى وحدة تحكّم Firebase باستخدام حساب Google.
- انقر على الزر لإنشاء مشروع جديد، ثم أدخِل اسم المشروع (على سبيل المثال،
Firebase-Web-Codelab). - انقر على متابعة.
- إذا طُلب منك ذلك، راجِع بنود Firebase واقبلها، ثم انقر على متابعة.
- (اختياري) فعِّل ميزة "المساعدة المستندة إلى الذكاء الاصطناعي" في وحدة تحكّم Firebase (المعروفة باسم "Gemini في Firebase").
- في هذا الدرس العملي، لا تحتاج إلى "إحصاءات Google"، لذا أوقِف خيار "إحصاءات Google".
- انقر على إنشاء مشروع، وانتظِر إلى أن يتم توفير مشروعك، ثم انقر على متابعة.
لمزيد من المعلومات عن مشاريع Firebase، اطّلِع على مقالة التعرّف على مشاريع Firebase.
تفعيل منتجات Firebase وإعدادها في وحدة التحكّم
يستخدم التطبيق الذي تنشئه العديد من منتجات Firebase المتاحة لتطبيقات الويب:
- مصادقة Firebase وواجهة مستخدم Firebase للسماح للمستخدمين بتسجيل الدخول إلى تطبيقك بسهولة
- Cloud Firestore لحفظ البيانات المنظَّمة على السحابة الإلكترونية وتلقّي إشعارات فورية عند تغيُّر البيانات
- قواعد الأمان في Firebase لتأمين قاعدة البيانات
تتطلّب بعض هذه المنتجات إعدادًا خاصًا أو يجب تفعيلها باستخدام وحدة تحكّم Firebase.
تفعيل تسجيل الدخول باستخدام البريد الإلكتروني في "مصادقة Firebase"
للسماح للمستخدمين بتسجيل الدخول إلى تطبيق الويب، ستستخدم طريقة تسجيل الدخول البريد الإلكتروني/كلمة المرور في هذا الدرس العملي:
- في اللوحة الجانبية اليمنى من وحدة تحكّم Firebase، انقر على إنشاء > المصادقة. بعد ذلك، انقر على البدء. أنت الآن في لوحة بيانات "المصادقة"، حيث يمكنك الاطّلاع على المستخدمين الذين اشتركوا، وإعداد موفّري خدمة تسجيل الدخول، وإدارة الإعدادات.

- انقر على علامة التبويب طريقة تسجيل الدخول (أو انقر هنا للانتقال مباشرةً إلى علامة التبويب).

- انقر على البريد الإلكتروني/كلمة المرور من خيارات موفّر الخدمة، ثم فعِّل الخيار تفعيل، وانقر على حفظ.

إعداد Cloud Firestore
يستخدم تطبيق الويب Cloud Firestore لحفظ رسائل المحادثات وتلقّي رسائل محادثات جديدة.
في ما يلي كيفية إعداد Cloud Firestore في مشروع Firebase:
- في اللوحة اليمنى من "وحدة تحكّم Firebase"، وسِّع إنشاء، ثم اختَر قاعدة بيانات Firestore.
- انقر على إنشاء قاعدة بيانات.
- اترك معرّف قاعدة البيانات مضبوطًا على
(default). - اختَر موقعًا لقاعدة البيانات، ثم انقر على التالي.
بالنسبة إلى تطبيق حقيقي، عليك اختيار موقع جغرافي قريب من المستخدمين. - انقر على بدء التشغيل في وضع الاختبار. اقرأ بيان إخلاء المسؤولية عن قواعد الأمان.
في وقت لاحق من هذا الدرس العملي، ستضيف قواعد الأمان لتأمين بياناتك. لا توزِّع تطبيقًا أو تعرضه بشكل علني بدون إضافة "قواعد الأمان" لقاعدة البيانات. - انقر على إنشاء.
5- إضافة Firebase وضبطها
بعد إنشاء مشروعك على Firebase وتفعيل بعض الخدمات، عليك إخبار الرمز البرمجي بأنّك تريد استخدام Firebase، بالإضافة إلى تحديد مشروع Firebase الذي تريد استخدامه.
إضافة مكتبات Firebase
لكي يستخدم تطبيقك Firebase، عليك إضافة مكتبات Firebase إلى التطبيق. وهناك طرق متعددة لإجراء ذلك، كما هو موضّح في مستندات Firebase. على سبيل المثال، يمكنك إضافة المكتبات من شبكة توصيل المحتوى (CDN) من Google، أو يمكنك تثبيتها محليًا باستخدام npm ثم تجميعها في تطبيقك إذا كنت تستخدم Browserify.
توفّر منصة StackBlitz تجميعًا تلقائيًا، لذا يمكنك إضافة مكتبات Firebase باستخدام عبارات الاستيراد. ستستخدم الإصدارات النموذجية (الإصدار 9) من المكتبات، ما يساعد في تقليل الحجم الإجمالي لصفحة الويب من خلال عملية تُعرف باسم "استبعاد الرموز غير المستخدَمة". يمكنك الاطّلاع على مزيد من المعلومات حول حِزم تطوير البرامج (SDK) النموذجية في المستندات.
لإنشاء هذا التطبيق، يمكنك استخدام مكتبات مصادقة Firebase وFirebaseUI وCloud Firestore. في هذا الدرس التطبيقي حول الترميز، تم تضمين عبارات الاستيراد التالية في أعلى ملف index.js، وسنستورد المزيد من الطرق من كل مكتبة من مكتبات Firebase أثناء تقدمنا:
// Import stylesheets
import './style.css';
// Firebase App (the core Firebase SDK) is always required
import { initializeApp } from 'firebase/app';
// Add the Firebase products and methods that you want to use
import {} from 'firebase/auth';
import {} from 'firebase/firestore';
import * as firebaseui from 'firebaseui';
إضافة تطبيق ويب على Firebase إلى مشروع Firebase
- ارجع إلى "وحدة تحكّم Firebase"، وانتقِل إلى صفحة النظرة العامة على مشروعك من خلال النقر على نظرة عامة على المشروع في أعلى يمين الصفحة.
- في وسط صفحة النظرة العامة على مشروعك، انقر على رمز الويب
لإنشاء تطبيق ويب جديد على Firebase.
- سجِّل التطبيق بالاسم المستعار تطبيق الويب.
- في هذا الدرس التطبيقي حول الترميز، لا تضع علامة في المربّع بجانب إعداد خدمة "استضافة Firebase" لهذا التطبيق أيضًا. ستستخدم لوحة المعاينة في StackBlitz في الوقت الحالي.
- انقر على تسجيل التطبيق.

- انسخ عنصر إعدادات Firebase إلى الحافظة.

- انقر على متابعة إلى وحدة التحكّم.أضِف عنصر إعداد Firebase إلى تطبيقك:
- في StackBlitz، انتقِل إلى ملف
index.js. - ابحث عن سطر التعليق
Add Firebase project configuration object here، ثم الصِق مقتطف الإعداد أسفل التعليق مباشرةً. - أضِف استدعاء الدالة
initializeAppلإعداد Firebase باستخدام إعدادات مشروع Firebase الفريدة.// ... // Add Firebase project configuration object here const firebaseConfig = { apiKey: "random-unique-string", authDomain: "your-projectId.firebaseapp.com", databaseURL: "https://your-projectId.firebaseio.com", projectId: "your-projectId", storageBucket: "your-projectId.firebasestorage.app", messagingSenderId: "random-unique-string", appId: "random-unique-string", }; // Initialize Firebase initializeApp(firebaseConfig);
6. إضافة ميزة تسجيل دخول المستخدم (الرد على الدعوة)
بعد إضافة Firebase إلى التطبيق، يمكنك إعداد زر الرد على الدعوة الذي يسجّل المستخدمين باستخدام مصادقة Firebase.
مصادقة المستخدمين باستخدام ميزة "تسجيل الدخول باستخدام البريد الإلكتروني" وFirebaseUI
ستحتاج إلى زر ردّ على الدعوة يطلب من المستخدم تسجيل الدخول باستخدام عنوان بريده الإلكتروني. يمكنك إجراء ذلك من خلال ربط FirebaseUI بزر الرد على الدعوة.FirebaseUI هي مكتبة تتيح لك واجهة مستخدم مُعدّة مسبقًا فوق Firebase المصادقة.
يتطلّب FirebaseUI إعدادًا (راجِع الخيارات في المستندات) يؤدي وظيفتَين:
- يُعلم FirebaseUI أنّك تريد استخدام طريقة تسجيل الدخول البريد الإلكتروني/كلمة المرور.
- يتعامل مع دالة الرجوع لعملية تسجيل دخول ناجحة ويعرض القيمة false لتجنُّب إعادة التوجيه. لا تريد إعادة تحميل الصفحة لأنّك بصدد إنشاء تطبيق ويب من صفحة واحدة.
إضافة الرمز اللازم لتهيئة FirebaseUI Auth
- في StackBlitz، انتقِل إلى الملف
index.js. - في أعلى الصفحة، ابحث عن عبارة الاستيراد
firebase/auth، ثم أضِفgetAuthوEmailAuthProvider، كما يلي:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider } from 'firebase/auth'; import {} from 'firebase/firestore'; - احفظ مرجعًا إلى عنصر المصادقة مباشرةً بعد
initializeApp، كما يلي:initializeApp(firebaseConfig); auth = getAuth(); - يُرجى العِلم أنّه تم توفير إعدادات FirebaseUI في الرمز الأوّلي. تم إعدادها مسبقًا لاستخدام موفّر مصادقة البريد الإلكتروني.
- في أسفل الدالة
main()فيindex.js، أضِف عبارة إعداد FirebaseUI على النحو التالي:async function main() { // ... // Initialize the FirebaseUI widget using Firebase const ui = new firebaseui.auth.AuthUI(auth); } main();
إضافة زر "الرد على الدعوة" إلى رمز HTML
- في StackBlitz، انتقِل إلى الملف
index.html. - أضِف رمز HTML لزر الرد على الدعوة داخل
event-details-containerكما هو موضّح في المثال أدناه.
احرص على استخدام قيمidنفسها كما هو موضّح أدناه، لأنّه في هذا الدرس التطبيقي حول الترميز، تتوفّر خطافات لهذه المعرّفات المحدّدة في ملفindex.js.
يُرجى العِلم أنّه في الملفindex.html، هناك حاوية تحمل رقم التعريفfirebaseui-auth-container. هذا هو المعرّف الذي ستمرّره إلى FirebaseUI للاحتفاظ بتفاصيل تسجيل الدخول. معاينة التطبيق<!-- ... --> <section id="event-details-container"> <!-- ... --> <!-- ADD THE RSVP BUTTON HERE --> <button id="startRsvp">RSVP</button> </section> <hr> <section id="firebaseui-auth-container"></section> <!-- ... -->
- اضبط أداة معالجة الأحداث على زر الردّ على الدعوة واستدعِ دالة بدء FirebaseUI. يُعلم هذا الرمز FirebaseUI بأنّك تريد عرض نافذة تسجيل الدخول.
أضِف الرمز التالي إلى أسفل الدالةmain()فيindex.js:async function main() { // ... // Listen to RSVP button clicks startRsvpButton.addEventListener("click", () => { ui.start("#firebaseui-auth-container", uiConfig); }); } main();
اختبار تسجيل الدخول إلى التطبيق
- في نافذة المعاينة في StackBlitz، انقر على زر RSVP لتسجيل الدخول إلى التطبيق.
- في هذا الدرس العملي، يمكنك استخدام أي عنوان بريد إلكتروني، حتى عنوان بريد إلكتروني مزيف، لأنّك لن تُعدّ خطوة لتأكيد عنوان البريد الإلكتروني في هذا الدرس العملي.
- إذا ظهرت لك رسالة خطأ تفيد
auth/operation-not-allowedأوThe given sign-in provider is disabled for this Firebase project، تأكَّد من أنّك فعّلت البريد الإلكتروني/كلمة المرور كمقدّم خدمة تسجيل الدخول في وحدة تحكّم Firebase.

- انتقِل إلى لوحة بيانات المصادقة في وحدة تحكّم Firebase. في علامة التبويب المستخدمون، من المفترض أن تظهر معلومات الحساب التي أدخلتها لتسجيل الدخول إلى التطبيق.

إضافة حالة المصادقة إلى واجهة المستخدم
بعد ذلك، تأكَّد من أنّ واجهة المستخدم تشير إلى أنّك سجّلت الدخول.
ستستخدم دالة معاودة الاتصال الخاصة بمستمع حالة مصادقة Firebase، والتي يتم إعلامها كلما تغيّرت حالة تسجيل الدخول للمستخدم. إذا كان هناك مستخدم مسجّل الدخول حاليًا، سيحوّل تطبيقك الزر "تأكيد الحضور" إلى زر "تسجيل الخروج".
- في StackBlitz، انتقِل إلى الملف
index.js. - في أعلى الصفحة، ابحث عن عبارة الاستيراد
firebase/auth، ثم أضِفsignOutوonAuthStateChanged، كما يلي:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider, signOut, onAuthStateChanged } from 'firebase/auth'; import {} from 'firebase/firestore'; - أضِف الرمز التالي في أسفل الدالة
main():async function main() { // ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; } else { startRsvpButton.textContent = 'RSVP'; } }); } main(); - في أداة معالجة أحداث الزر، تحقَّق ممّا إذا كان هناك مستخدم حالي وسجِّل خروجه. لإجراء ذلك، استبدِل
startRsvpButton.addEventListenerالحالي بما يلي:// ... // Called when the user clicks the RSVP button startRsvpButton.addEventListener('click', () => { if (auth.currentUser) { // User is signed in; allows user to sign out signOut(auth); } else { // No user is signed in; allows user to sign in ui.start('#firebaseui-auth-container', uiConfig); } });
من المفترض أن يعرض الزر في تطبيقك الآن تسجيل الخروج، وأن يعود إلى الرد على الدعوة عند النقر عليه.
معاينة التطبيق

7. كتابة الرسائل إلى Cloud Firestore
من الرائع معرفة أنّ هناك مستخدمين سيأتون إلى تطبيقك، ولكن لنقدّم للضيوف شيئًا آخر يمكنهم فعله في التطبيق، مثل ترك رسائل في سجل الزوار. يمكنهم مشاركة سبب حماسهم للمشاركة أو الأشخاص الذين يأملون مقابلتهم.
لتخزين رسائل المحادثة التي يكتبها المستخدمون في التطبيق، عليك استخدام Cloud Firestore.
نموذج البيانات
Cloud Firestore هي قاعدة بيانات NoSQL، ويتم تقسيم البيانات المخزّنة في قاعدة البيانات إلى مجموعات ومستندات وحقول ومجموعات فرعية. سيتم تخزين كل رسالة من المحادثة كمستند في مجموعة ذات مستوى أعلى تُسمى guestbook.

إضافة رسائل إلى Firestore
في هذا القسم، ستضيف وظيفة تتيح للمستخدمين كتابة رسائل جديدة في قاعدة البيانات. أولاً، عليك إضافة رمز HTML لعناصر واجهة المستخدم (حقل الرسالة وزر الإرسال). بعد ذلك، يمكنك إضافة الرمز الذي يربط هذه العناصر بقاعدة البيانات.
لإضافة عناصر واجهة المستخدم الخاصة بحقل الرسالة وزر الإرسال، اتّبِع الخطوات التالية:
- في StackBlitz، انتقِل إلى الملف
index.html. - ابحث عن
guestbook-container، ثم أضِف رمز HTML التالي لإنشاء نموذج يتضمّن حقل إدخال الرسالة وزر الإرسال.<!-- ... --> <section id="guestbook-container"> <h2>Discussion</h2> <form id="leave-message"> <label>Leave a message: </label> <input type="text" id="message"> <button type="submit"> <i class="material-icons">send</i> <span>SEND</span> </button> </form> </section> <!-- ... -->
معاينة التطبيق

سيؤدي النقر على الزر إرسال إلى تشغيل مقتطف الرمز البرمجي أدناه. يضيف محتوى حقل إدخال الرسالة إلى مجموعة guestbook في قاعدة البيانات. على وجه التحديد، تضيف طريقة addDoc محتوى الرسالة إلى مستند جديد (مع معرّف تم إنشاؤه تلقائيًا) إلى المجموعة guestbook.
- في StackBlitz، انتقِل إلى الملف
index.js. - في أعلى الصفحة، ابحث عن عبارة الاستيراد
firebase/firestore، ثم أضِفgetFirestoreوaddDocوcollection، كما يلي:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider, signOut, onAuthStateChanged } from 'firebase/auth'; import { getFirestore, addDoc, collection } from 'firebase/firestore'; - سنحفظ الآن مرجعًا إلى عنصر Firestore
dbمباشرةً بعدinitializeApp:initializeApp(firebaseConfig); auth = getAuth(); db = getFirestore(); - في أسفل الدالة
main()، أضِف الرمز التالي.
يُرجى العِلم أنّauth.currentUser.uidهو إشارة إلى المعرّف الفريد الذي يتم إنشاؤه تلقائيًا والذي توفّره خدمة "مصادقة Firebase" لجميع المستخدمين الذين سجّلوا الدخول.async function main() { // ... // Listen to the form submission form.addEventListener('submit', async e => { // Prevent the default form redirect e.preventDefault(); // Write a new message to the database collection "guestbook" addDoc(collection(db, 'guestbook'), { text: input.value, timestamp: Date.now(), name: auth.currentUser.displayName, userId: auth.currentUser.uid }); // clear message input field input.value = ''; // Return false to avoid redirect return false; }); } main();
عرض دفتر الضيوف للمستخدمين الذين سجّلوا الدخول فقط
لا تريد أن يرى أي شخص محادثة الضيوف. يمكنك اتّخاذ إجراء واحد لتأمين المحادثة، وهو السماح للمستخدمين الذين سجّلوا الدخول فقط بالاطّلاع على دفتر الضيوف. مع ذلك، بالنسبة إلى تطبيقاتك، عليك أيضًا تأمين قاعدة البيانات باستخدام قواعد الأمان في Firebase. (ستجد المزيد من المعلومات عن قواعد الأمان في وقت لاحق من هذا الدرس العملي).
- في StackBlitz، انتقِل إلى الملف
index.js. - عدِّل أداة معالجة الأحداث
onAuthStateChangedلإخفاء دفتر الضيوف وإظهاره.// ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none'; } });
اختبار إرسال الرسائل
- تأكَّد من تسجيل الدخول إلى التطبيق.
- أدخِل رسالة مثل "مرحبًا"، ثم انقر على إرسال.
يؤدي هذا الإجراء إلى كتابة الرسالة في قاعدة بيانات Cloud Firestore. ومع ذلك، لن تظهر لك الرسالة بعد في تطبيق الويب الفعلي لأنّه لا يزال عليك تنفيذ عملية استرداد البيانات. ستنفّذ هذه الخطوة في الصفحة التالية.
ولكن يمكنك الاطّلاع على الرسالة المُضافة حديثًا في وحدة تحكّم Firebase.
في وحدة تحكّم Firebase، في لوحة بيانات قاعدة بيانات Firestore، من المفترض أن ترى المجموعة guestbook التي تتضمّن الرسالة التي أضفتها مؤخرًا. إذا واصلت إرسال الرسائل، ستتضمّن مجموعة سجلّ الزوّار العديد من المستندات، مثل ما يلي:
وحدة تحكُّم Firebase

8. قراءة الرسائل
مزامنة الرسائل
يسرّنا أنّ بإمكان الضيوف كتابة رسائل في قاعدة البيانات، ولكن لا يمكنهم الاطّلاع عليها في التطبيق بعد.
لعرض الرسائل، عليك إضافة متتبِّعات يتم تشغيلها عند تغيير البيانات، ثم إنشاء عنصر في واجهة المستخدم يعرض الرسائل الجديدة.
ستضيف رمزًا برمجيًا يتلقّى الرسائل المضافة حديثًا من التطبيق. أولاً، أضِف قسمًا في HTML لعرض الرسائل:
- في StackBlitz، انتقِل إلى الملف
index.html. - في
guestbook-container، أضِف قسمًا جديدًا بالمعرّفguestbook.<!-- ... --> <section id="guestbook-container"> <h2>Discussion</h2> <form><!-- ... --></form> <section id="guestbook"></section> </section> <!-- ... -->
بعد ذلك، سجِّل متتبِّع الأحداث الذي يستمع إلى التغييرات التي تم إجراؤها على البيانات:
- في StackBlitz، انتقِل إلى الملف
index.js. - في أعلى الصفحة، ابحث عن عبارة الاستيراد
firebase/firestore، ثم أضِفqueryوorderByوonSnapshot، كما يلي:// ... import { getFirestore, addDoc, collection, query, orderBy, onSnapshot } from 'firebase/firestore'; - في أسفل الدالة
main()، أضِف الرمز التالي لتكرار جميع المستندات (رسائل دفتر الضيوف) في قاعدة البيانات. لمزيد من المعلومات حول ما يحدث في هذا الرمز، اطّلِع على المعلومات الواردة أسفل المقتطف.async function main() { // ... // Create query for messages const q = query(collection(db, 'guestbook'), orderBy('timestamp', 'desc')); onSnapshot(q, snaps => { // Reset page guestbook.innerHTML = ''; // Loop through documents in database snaps.forEach(doc => { // Create an HTML entry for each document and add it to the chat const entry = document.createElement('p'); entry.textContent = doc.data().name + ': ' + doc.data().text; guestbook.appendChild(entry); }); }); } main();
للاستماع إلى الرسائل في قاعدة البيانات، أنشأت طلب بحث في مجموعة معيّنة باستخدام الدالة collection. يستمع الرمز البرمجي أعلاه إلى التغييرات في المجموعة guestbook، حيث يتم تخزين رسائل المحادثة. يتم أيضًا ترتيب الرسائل حسب التاريخ، باستخدام orderBy('timestamp', 'desc') لعرض أحدث الرسائل في الأعلى.
تتلقّى الدالة onSnapshot مَعلمتَين: طلب البحث الذي سيتم استخدامه ودالة ردّ الاتصال. يتم تشغيل دالة ردّ الاتصال عند حدوث أي تغييرات في المستندات التي تتطابق مع طلب البحث. قد يحدث ذلك إذا تم حذف رسالة أو تعديلها أو إضافتها. لمزيد من المعلومات، يُرجى الاطّلاع على مستندات Cloud Firestore.
اختبار مزامنة الرسائل
تتم مزامنة البيانات تلقائيًا وفوريًا مع العملاء المشتركين في قاعدة البيانات على Cloud Firestore.
- يجب أن تظهر الرسائل التي أنشأتها سابقًا في قاعدة البيانات في التطبيق. يمكنك كتابة رسائل جديدة، وستظهر على الفور.
- إذا فتحت مساحة عملك في نوافذ أو علامات تبويب متعددة، ستتم مزامنة الرسائل في الوقت الفعلي على جميع علامات التبويب.
- (اختياري) يمكنك محاولة حذف الرسائل أو تعديلها أو إضافة رسائل جديدة يدويًا مباشرةً في قسم قاعدة البيانات في وحدة تحكّم Firebase، ومن المفترض أن تظهر أي تغييرات في واجهة المستخدم.
تهانينا! أنت تقرأ مستندات Cloud Firestore في تطبيقك.
معاينة التطبيق

9. إعداد قواعد الأمان الأساسية
لقد أعددت Cloud Firestore في البداية لاستخدام وضع الاختبار، ما يعني أنّ قاعدة البيانات مفتوحة للقراءة والكتابة. ومع ذلك، يجب استخدام وضع الاختبار في المراحل الأولى من التطوير فقط. وفقًا لأفضل الممارسات، عليك إعداد قواعد الأمان لقاعدة البيانات أثناء تطوير تطبيقك، لأنّ الأمان يجب أن يكون جزءًا لا يتجزأ من بنية تطبيقك وسلوكه.
تتيح لك "قواعد الأمان" التحكّم في الوصول إلى المستندات والمجموعات في قاعدة البيانات. يتيح لك بناء الجملة المرن للقواعد إنشاء قواعد تتطابق مع أي شيء، بدءًا من جميع عمليات الكتابة إلى قاعدة البيانات بأكملها وصولاً إلى العمليات على مستند معيّن.
يمكنك كتابة قواعد الأمان في Cloud Firestore من خلال وحدة تحكّم Firebase باتّباع الخطوات التالية:
- في قسم الإنشاء في وحدة تحكّم Firebase، انقر على قاعدة بيانات Firestore، ثم اختَر علامة التبويب القواعد (أو انقر هنا للانتقال مباشرةً إلى علامة التبويب القواعد).
- من المفترض أن تظهر لك قواعد الأمان التلقائية التالية، مع حدّ زمني للوصول العام يبلغ أسبوعَين من تاريخ اليوم.

تحديد المجموعات
أولاً، حدِّد المجموعات التي يكتب التطبيق البيانات فيها.
- احذف عبارة
match /{document=**}الحالية، لكي تبدو قواعدك على النحو التالي:rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { } } - في
match /databases/{database}/documents، حدِّد المجموعة التي تريد تأمينها:rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { // You'll add rules here in the next step. } }
إضافة قواعد الأمان
بما أنّك استخدمت المعرّف الفريد للمصادقة كحقل في كل مستند من مستندات سجل الزوار، يمكنك الحصول على المعرّف الفريد للمصادقة والتحقّق من أنّ أي شخص يحاول الكتابة في المستند لديه معرّف فريد مطابق للمصادقة.
- أضِف قواعد القراءة والكتابة إلى مجموعة القواعد كما هو موضّح أدناه:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { allow read: if request.auth.uid != null; allow create: if request.auth.uid == request.resource.data.userId; } } } - انقر على نشر لتفعيل القواعد الجديدة.الآن، في دفتر الضيوف، يمكن للمستخدمين الذين سجّلوا الدخول فقط قراءة الرسائل (أي رسالة)، ولكن يمكنك إنشاء رسالة باستخدام معرّف المستخدم فقط. ولا نسمح أيضًا بتعديل الرسائل أو حذفها.
إضافة قواعد التحقّق
- أضِف ميزة التحقّق من صحة البيانات للتأكّد من توفّر جميع الحقول المتوقّعة في المستند:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { allow read: if request.auth.uid != null; allow create: if request.auth.uid == request.resource.data.userId && "name" in request.resource.data && "text" in request.resource.data && "timestamp" in request.resource.data; } } } - انقر على نشر لنشر القواعد الجديدة.
إعادة ضبط المتتبّعين
بما أنّ تطبيقك لا يسمح الآن إلا للمستخدمين الذين تمّت المصادقة عليهم بتسجيل الدخول، عليك نقل طلب البحث firestore الخاص بسجل الزوار إلى داخل متتبِّع المصادقة. بخلاف ذلك، ستحدث أخطاء في الأذونات وسيتم قطع اتصال التطبيق عند تسجيل المستخدم الخروج.
- في StackBlitz، انتقِل إلى الملف
index.js. - اسحب أداة معالجة مجموعة سجل الزوار
onSnapshotإلى دالة جديدة باسمsubscribeGuestbook. عيِّن أيضًا نتائج الدالةonSnapshotإلى المتغيرguestbookListener.
onSnapshotالمستمع يُرجع في Firestore دالة إلغاء اشتراك يمكنك استخدامها لإلغاء مستمع اللقطة لاحقًا.// ... // Listen to guestbook updates function subscribeGuestbook() { const q = query(collection(db, 'guestbook'), orderBy('timestamp', 'desc')); guestbookListener = onSnapshot(q, snaps => { // Reset page guestbook.innerHTML = ''; // Loop through documents in database snaps.forEach(doc => { // Create an HTML entry for each document and add it to the chat const entry = document.createElement('p'); entry.textContent = doc.data().name + ': ' + doc.data().text; guestbook.appendChild(entry); }); }); } - أضِف دالة جديدة أدناه باسم
unsubscribeGuestbook. تحقَّق ممّا إذا كان المتغيّرguestbookListenerليس قيمة فارغة، ثم استدعِ الوظيفة لإلغاء المتتبِّع.// ... // Unsubscribe from guestbook updates function unsubscribeGuestbook() { if (guestbookListener != null) { guestbookListener(); guestbookListener = null; } }
وأخيرًا، أضِف الدوال الجديدة إلى عملية الاسترجاع onAuthStateChanged.
- أضِف
subscribeGuestbook()في أسفلif (user). - أضِف
unsubscribeGuestbook()في أسفل عبارةelse.// ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; // Subscribe to the guestbook collection subscribeGuestbook(); } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none'; // Unsubscribe from the guestbook collection unsubscribeGuestbook(); } });
10. خطوة إضافية: ممارسة ما تعلّمته
تسجيل حالة ردّ الضيف على الدعوة
في الوقت الحالي، يتيح تطبيقك للمستخدمين بدء محادثة إذا كانوا مهتمين بالحدث. بالإضافة إلى ذلك، الطريقة الوحيدة لمعرفة ما إذا كان أحد المستخدمين سيشارك في المحادثة هي إذا نشر ذلك في المحادثة. لننظّم الأمور ونُطلع الآخرين على عدد الأشخاص الذين سيحضرون.
ستضيف زر تبديل لتسجيل الأشخاص الذين يريدون حضور الحدث، ثم ستجمع عدد الأشخاص الذين سيحضرون.
- في StackBlitz، انتقِل إلى الملف
index.html. - في
guestbook-container، أضِف مجموعة من أزرار نعم ولا، على النحو التالي:<!-- ... --> <section id="guestbook-container"> <h2>Are you attending?</h2> <button id="rsvp-yes">YES</button> <button id="rsvp-no">NO</button> <h2>Discussion</h2> <!-- ... --> </section> <!-- ... -->
معاينة التطبيق

بعد ذلك، سجِّل متتبِّع النقرات على الأزرار. إذا نقر المستخدم على نعم، استخدِم معرّف UID للمصادقة لحفظ الردّ في قاعدة البيانات.
- في StackBlitz، انتقِل إلى الملف
index.js. - في أعلى الصفحة، ابحث عن عبارة الاستيراد
firebase/firestore، ثم أضِفdocوsetDocوwhere، كما يلي:// ... // Add the Firebase products and methods that you want to use import { getFirestore, addDoc, collection, query, orderBy, onSnapshot, doc, setDoc, where } from 'firebase/firestore'; - في أسفل الدالة
main()، أضِف الرمز التالي للاستماع إلى حالة الردّ على الدعوة:async function main() { // ... // Listen to RSVP responses rsvpYes.onclick = async () => { }; rsvpNo.onclick = async () => { }; } main(); - بعد ذلك، أنشئ مجموعة جديدة باسم
attendees، ثم سجِّل مرجع مستند عند النقر على أي من زرَّي الردّ على الدعوة. اضبط قيمة المرجع علىtrueأوfalseاستنادًا إلى الزر الذي تم النقر عليه.
أولاً، بالنسبة إلىrsvpYes: ثم، يتم تكرار العملية نفسها مع// ... // Listen to RSVP responses rsvpYes.onclick = async () => { // Get a reference to the user's document in the attendees collection const userRef = doc(db, 'attendees', auth.currentUser.uid); // If they RSVP'd yes, save a document with attendi()ng: true try { await setDoc(userRef, { attending: true }); } catch (e) { console.error(e); } };rsvpNo، ولكن بالقيمةfalse:rsvpNo.onclick = async () => { // Get a reference to the user's document in the attendees collection const userRef = doc(db, 'attendees', auth.currentUser.uid); // If they RSVP'd yes, save a document with attending: true try { await setDoc(userRef, { attending: false }); } catch (e) { console.error(e); } };
تعديل "قواعد الأمان"
بما أنّك أعددت بعض القواعد سابقًا، سيتم رفض البيانات الجديدة التي تضيفها باستخدام الأزرار.
السماح بإضافة محتوى إلى مجموعة attendees
عليك تعديل القواعد للسماح بإضافة محتوى إلى مجموعة attendees.
- بالنسبة إلى مجموعة
attendees، بما أنّك استخدمت المعرّف الفريد للمصادقة كاسم للمستند، يمكنك الحصول عليه والتحقّق من أنّuidللمرسِل هو نفسه المستند الذي يكتبه. ستسمح للجميع بقراءة قائمة الضيوف (لأنّها لا تتضمّن أي بيانات خاصة)، ولكن يجب أن يتمكّن المنشئ فقط من تعديلها.rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // ... // match /attendees/{userId} { allow read: if true; allow write: if request.auth.uid == userId; } } } - انقر على نشر لنشر القواعد الجديدة.
إضافة قواعد التحقّق
- أضِف بعض قواعد التحقّق من صحة البيانات للتأكّد من أنّ جميع الحقول المتوقّعة متوفّرة في المستند:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // ... // match /attendees/{userId} { allow read: if true; allow write: if request.auth.uid == userId && "attending" in request.resource.data; } } } - لا تنسَ النقر على نشر لتفعيل قواعدك.
(اختياري) يمكنك الآن الاطّلاع على نتائج النقر على الأزرار. انتقِل إلى لوحة بيانات Cloud Firestore في وحدة تحكّم Firebase.
قراءة حالة الردّ على الدعوة
بعد تسجيل الردود، لنطّلِع على المشاركين ونعرضهم في واجهة المستخدم.
- في StackBlitz، انتقِل إلى الملف
index.html. - في
description-container، أضِف عنصرًا جديدًا بالمعرّفnumber-attending.<!-- ... --> <section id="description-container"> <!-- ... --> <p id="number-attending"></p> </section> <!-- ... -->
بعد ذلك، سجِّل متتبِّع الأحداث لمجموعة attendees واحتسِب عدد الردود نعم:
- في StackBlitz، انتقِل إلى الملف
index.js. - في أسفل الدالة
main()، أضِف الرمز التالي للاستماع إلى حالة الرد على الدعوة واحتساب عدد النقرات على نعم.async function main() { // ... // Listen for attendee list const attendingQuery = query( collection(db, 'attendees'), where('attending', '==', true) ); const unsubscribe = onSnapshot(attendingQuery, snap => { const newAttendeeCount = snap.docs.length; numberAttending.innerHTML = newAttendeeCount + ' people going'; }); } main();
أخيرًا، لنبرز الزر الذي يتوافق مع الحالة الحالية.
- أنشئ دالة تتحقّق ممّا إذا كان معرّف UID الحالي للمصادقة يتضمّن إدخالاً في المجموعة
attendees، ثم اضبط فئة الزر علىclicked.// ... // Listen for attendee list function subscribeCurrentRSVP(user) { const ref = doc(db, 'attendees', user.uid); rsvpListener = onSnapshot(ref, doc => { if (doc && doc.data()) { const attendingResponse = doc.data().attending; // Update css classes for buttons if (attendingResponse) { rsvpYes.className = 'clicked'; rsvpNo.className = ''; } else { rsvpYes.className = ''; rsvpNo.className = 'clicked'; } } }); } - لننشئ أيضًا دالة لإلغاء الاشتراك. سيتم استخدام هذا المعرّف عندما يسجّل المستخدم الخروج.
// ... function unsubscribeCurrentRSVP() { if (rsvpListener != null) { rsvpListener(); rsvpListener = null; } rsvpYes.className = ''; rsvpNo.className = ''; } - استدعِ الدوال من أداة معالجة المصادقة.
// ... // Listen to the current Auth state // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; // Subscribe to the guestbook collection subscribeGuestbook(); // Subscribe to the user's RSVP subscribeCurrentRSVP(user); } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none' ; // Unsubscribe from the guestbook collection unsubscribeGuestbook(); // Unsubscribe from the guestbook collection unsubscribeCurrentRSVP(); } }); - جرِّب تسجيل الدخول بصفتك عدة مستخدمين ولاحظ زيادة العدد مع كل نقرة إضافية على الزر نعم.
معاينة التطبيق

11. تهانينا!
لقد استخدمت Firebase لإنشاء تطبيق ويب تفاعلي في الوقت الفعلي.
المواضيع التي تناولناها
- مصادقة Firebase
- FirebaseUI
- Cloud Firestore
- قواعد الأمان في Firebase
الخطوات التالية
- هل تريد معرفة المزيد عن سير عمل المطوّرين في Firebase؟ يمكنك الاطّلاع على درس Firebase التطبيقي حول الترميز للتعرّف على كيفية اختبار تطبيقك وتشغيله بالكامل على جهازك.
- هل تريد معرفة المزيد عن منتجات Firebase الأخرى؟ ربما تريد تخزين ملفات الصور التي يحمّلها المستخدمون؟ أو إرسال إشعارات إلى المستخدمين؟ يمكنك الاطّلاع على الدرس التطبيقي حول الترميز على الويب في Firebase للحصول على درس تطبيقي يتناول المزيد من التفاصيل حول العديد من منتجات Firebase للويب.
- مزيد من المعلومات حول Cloud Firestore ربما تريد معرفة المزيد عن المجموعات الفرعية والمعاملات؟ انتقِل إلى الدرس التطبيقي حول الترميز الخاص بتطبيق الويب Cloud Firestore للحصول على درس تطبيقي يتناول Cloud Firestore بتفصيل أكبر. يمكنك أيضًا الاطّلاع على سلسلة YouTube هذه للتعرّف على Cloud Firestore.
مزيد من المعلومات
- موقع Firebase الإلكتروني: firebase.google.com
- قناة Firebase على YouTube
كيف كانت النتيجة؟
يسرّنا تلقّي ملاحظاتك. يُرجى ملء نموذج (مختصر جدًا) هنا.