التعرُّف على Firebase للويب

1- نظرة عامة

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

لقطة شاشة لهذه الخطوة

ما ستتعرّف عليه

  • مصادقة المستخدمين باستخدام Firebase Authentication وFirebaseUI
  • مزامنة البيانات باستخدام Cloud Firestore
  • كتابة قواعد أمان Firebase لتأمين قاعدة بيانات

المتطلبات

  • متصفّح من اختيارك، مثل Chrome
  • الوصول إلى stackblitz.com (لا يلزم توفُّر حساب أو تسجيل الدخول)
  • حساب Google، مثل حساب Gmail ننصحك باستخدام حساب البريد الإلكتروني الذي تستخدمه حاليًا لحسابك على GitHub. يتيح لك ذلك استخدام الميزات المتقدّمة في StackBlitz.
  • نموذج التعليمات البرمجية في ورشة التعلم اطّلِع على الخطوة التالية لمعرفة كيفية الحصول على الرمز.

2- الحصول على الرمز المبدئي

في هذا الدرس التطبيقي، يمكنك إنشاء تطبيق باستخدام StackBlitz، وهو محرِّر على الإنترنت يتضمّن العديد من عمليات سير العمل في Firebase. لا يتطلّب StackBlitz تثبيت أي برامج أو حساب StackBlitz خاص.

يتيح لك StackBlitz مشاركة المشاريع مع الآخرين. يمكن للمستخدمين الآخرين الذين لديهم عنوان URL لمشروعك على StackBlitz الاطّلاع على الرمز البرمجي وإنشاء نسخة من مشروعك، ولكن لا يمكنهم تعديل مشروعك على StackBlitz.

  1. انتقِل إلى عنوان URL هذا للحصول على الرمز البرمجي الأوّلي: https://stackblitz.com/edit/firebase-gtk-web-start
  2. في أعلى صفحة StackBlitz، انقر على Fork (نسخ):

لقطة شاشة لهذه الخطوة

لديك الآن نسخة من الرمز البرمجي الأوّلي كمشروع StackBlitz خاص بك، وهو يتضمّن اسمًا فريدًا وعنوان URL فريدًا. يتم حفظ جميع ملفاتك وتغييراتك في مشروع StackBlitz هذا.

3- تعديل معلومات الحدث

توفّر المواد الأساسية لهذا الدرس التطبيقي حول الترميز بعض البنية لتطبيق الويب، بما في ذلك بعض جداول الأنماط وبعض حاويات HTML للتطبيق. وفي وقت لاحق من هذا الدرس التطبيقي، ستربط هذه الحاويات بمنصّة Firebase.

للبدء، لنتعرّف أكثر على واجهة StackBlitz.

  1. في StackBlitz، افتح ملف index.html.
  2. ابحث عن 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

  1. سجِّل الدخول إلى Firebase.
  2. في "وحدة تحكّم Firebase"، انقر على إضافة مشروع (أو إنشاء مشروع)، ثمّ أدخِل اسمًا لمشروعك على Firebase وهو Firebase-Web-Codelab.

    لقطة شاشة لهذه الخطوة

  3. انقر على خيارات إنشاء المشروع. اقبل بنود Firebase إذا طُلب منك ذلك. في شاشة "إحصاءات Google"، انقر على "عدم التفعيل" لأنّك لن تستخدم "إحصاءات Google" لهذا التطبيق.

لمزيد من المعلومات عن مشاريع Firebase، اطّلِع على مقالة فهم مشاريع Firebase.

تفعيل منتجات Firebase وإعدادها في وحدة التحكّم

يستخدم التطبيق الذي تنشئه العديد من منتجات Firebase المتاحة لتطبيقات الويب:

  • Firebase Authentication وواجهة مستخدم Firebase للسماح لمستخدميك بتسجيل الدخول إلى تطبيقك بسهولة
  • Cloud Firestore لحفظ البيانات المنظَّمة في السحابة الإلكترونية والحصول على إشعار فوري عند تغيُّر البيانات
  • قواعد أمان Firebase لتأمين قاعدة بياناتك

وتتطلّب بعض هذه المنتجات إعدادًا خاصًا أو تفعيلها باستخدام وحدة تحكُّم Firebase.

تفعيل تسجيل الدخول باستخدام البريد الإلكتروني في ميزة "مصادقة Firebase"

للسماح للمستخدمين بتسجيل الدخول إلى تطبيق الويب، ستستخدم طريقة تسجيل الدخول باستخدام البريد الإلكتروني/كلمة المرور في هذا الدليل التعليمي للترميز:

  1. في اللوحة اليمنى من وحدة تحكّم Firebase، انقر على الإنشاء > المصادقة. بعد ذلك، انقر على البدء. لقد انتقلت الآن إلى لوحة بيانات المصادقة، حيث يمكنك الاطّلاع على المستخدمين الذين سجّلوا الدخول وضبط مقدّمي خدمات تسجيل الدخول وإدارة الإعدادات.

    لقطة شاشة لهذه الخطوة

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

    لقطة شاشة لهذه الخطوة

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

    لقطة شاشة لهذه الخطوة

إعداد Cloud Firestore

يستخدم تطبيق الويب Cloud Firestore لحفظ رسائل المحادثات وتلقّي رسائل محادثات جديدة.

في ما يلي كيفية إعداد Cloud Firestore في مشروعك على Firebase:

  1. في اللوحة اليمنى من "وحدة تحكّم Firebase"، وسِّع الإنشاء، ثم اختَر قاعدة بيانات Firestore.
  2. انقر على إنشاء قاعدة بيانات.
  3. اترك رقم تعريف قاعدة البيانات مضبوطًا على (default).
  4. اختَر موقعًا لقاعدة بياناتك، ثم انقر على التالي.
    بالنسبة إلى التطبيق الحقيقي، عليك اختيار موقع قريب من المستخدمين.
  5. انقر على البدء في وضع الاختبار. اقرأ بيان إخلاء المسؤولية عن قواعد الأمان.
    في وقت لاحق من هذا الدليل التعليمي، ستضيف قواعد أمان لتأمين بياناتك. لا توزِّع تطبيقًا علنًا أو تعرضه بدون إضافة قواعد أمان لقاعدة بياناتك.
  6. انقر على إنشاء.

5- إضافة Firebase وضبطه

بعد إنشاء مشروعك على Firebase وتفعيل بعض الخدمات، عليك إخبار الرمز البرمجي بأنّك تريد استخدام Firebase، بالإضافة إلى مشروع Firebase الذي تريد استخدامه.

إضافة مكتبات Firebase

لكي يستخدم تطبيقك Firebase، عليك إضافة مكتبات Firebase إليه. وهناك طرق متعدّدة لإجراء ذلك، كما هو موضّح في مستندات Firebase. على سبيل المثال، يمكنك إضافة المكتبات من شبكة توصيل المحتوى (CDN) من Google، أو يمكنك تثبيتها محليًا باستخدام npm ثم حزمها في تطبيقك إذا كنت تستخدم Browserify.

توفّر أداة StackBlitz تجميعًا تلقائيًا، ما يتيح لك إضافة مكتبات Firebase باستخدام عبارات الاستيراد. ستستخدم الإصدارات المكوّنة من وحدات (الإصدار 9) من المكتبات، ما يساعد في تقليل الحجم الإجمالي لصفحة الويب من خلال عملية تُعرف باسم "إزالة العناصر غير الضرورية". يمكنك الاطّلاع على مزيد من المعلومات حول حِزم SDK المكوّنة من وحدات في المستندات.

لإنشاء هذا التطبيق، يمكنك استخدام مكتبات Firebase Authentication و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

  1. في "وحدة تحكّم Firebase"، انتقِل إلى صفحة النظرة العامة على مشروعك بالنقر على نظرة عامة على المشروع في أعلى يمين الصفحة.
  2. في منتصف صفحة النظرة العامة على مشروعك، انقر على رمز الويب رمز تطبيق الويبلإنشاء تطبيق ويب جديد على Firebase.

    لقطة شاشة لهذه الخطوة

  3. سجِّل التطبيق باستخدام الاسم المعرِّف تطبيق الويب.
  4. في هذا الدليل التعليمي حول رموز البرامج، لا ضَع علامة في المربّع بجانب إعداد ميزة "استضافة Firebase" لهذا التطبيق أيضًا. ستستخدم لوحة المعاينة في StackBlitz في الوقت الحالي.
  5. انقر على تسجيل التطبيق.

    لقطة شاشة لهذه الخطوة

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

    لقطة شاشة لهذه الخطوة

  7. انقر على متابعة إلى وحدة التحكّم.أضِف عنصر إعدادات Firebase إلى تطبيقك:
  8. في StackBlitz، انتقِل إلى ملف index.js.
  9. حدِّد مكان سطر التعليق Add Firebase project configuration object here، ثم الصِق مقتطف الإعدادات أسفل التعليق مباشرةً.
  10. أضِف طلب الدالة 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 إلى التطبيق، يمكنك إعداد زرّ RSVP يُسجِّل المستخدمين باستخدام Firebase Authentication.

مصادقة المستخدمين باستخدام ميزة "تسجيل الدخول باستخدام عنوان البريد الإلكتروني" وFirebaseUI

ستحتاج إلى زر "الردّ على الدعوة" يطلب من المستخدم تسجيل الدخول باستخدام عنوان بريده الإلكتروني. يمكنك إجراء ذلك من خلال ربط FirebaseUI بزر RSVP.وFirebaseUI هي مكتبة تمنحك واجهة مستخدم مُنشأة مسبقًا بالإضافة إلى Firebase Auth.

تتطلّب FirebaseUI عملية ضبط (اطّلِع على الخيارات في المستندات) تؤدي إلى إجراء أمرَين:

  • تُعلم FirebaseUI بأنّك تريد استخدام طريقة تسجيل الدخول البريد الإلكتروني/كلمة المرور.
  • تعالج طلب إعادة الاتصال في حال تسجيل الدخول بنجاح وتُرجع قيمة false لتجنُّب إعادة التوجيه. لا تريد إعادة تحميل الصفحة لأنّك بصدد إنشاء تطبيق ويب مكوّن من صفحة واحدة.

أضِف الرمز لتهيئة FirebaseUI Auth.

  1. في StackBlitz، انتقِل إلى ملف index.js.
  2. في أعلى الصفحة، ابحث عن عبارة الاستيراد 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';
    
  3. احفظ إشارة إلى عنصر المصادقة بعد initializeApp مباشرةً، على النحو التالي:
    initializeApp(firebaseConfig);
    auth = getAuth();
    
  4. يُرجى العلم أنّه سبق أن تم توفير إعدادات FirebaseUI في الرمز المبدئي. تم إعداده لاستخدام مقدّم خدمة مصادقة البريد الإلكتروني.
  5. في أسفل دالة main() في index.js، أضِف عبارة إعداد FirebaseUI، على النحو التالي:
    async function main() {
      // ...
    
      // Initialize the FirebaseUI widget using Firebase
      const ui = new firebaseui.auth.AuthUI(auth);
    }
    main();
    
    

إضافة زر "الردّ على الدعوة" إلى ملف HTML

  1. في StackBlitz، انتقِل إلى ملف index.html.
  2. أضِف رمز 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>
    <!-- ... -->
    
    معاينة التطبيق

    لقطة شاشة لهذه الخطوة

  3. يمكنك إعداد مستمع على زر RSVP واستدعاء وظيفة بدء FirebaseUI. يُعلم هذا الإجراء FirebaseUI بأنّك تريد عرض نافذة تسجيل الدخول.

    أضِف الرمز التالي إلى أسفل دالة main() في index.js:
    async function main() {
      // ...
    
      // Listen to RSVP button clicks
      startRsvpButton.addEventListener("click",
       () => {
            ui.start("#firebaseui-auth-container", uiConfig);
      });
    }
    main();
    

اختبار تسجيل الدخول إلى التطبيق

  1. في نافذة معاينة StackBlitz، انقر على زر RSVP لتسجيل الدخول إلى التطبيق.
    • في هذا الدليل التعليمي حول الرموز البرمجية، يمكنك استخدام أي عنوان بريد إلكتروني، حتى عنوان بريد إلكتروني مزيّف، لأنّك لن تُعدّ خطوة إثبات ملكية عنوان البريد الإلكتروني في هذا الدليل التعليمي حول الرموز البرمجية.
    • إذا ظهرت لك رسالة خطأ تشير إلى auth/operation-not-allowed أو The given sign-in provider is disabled for this Firebase project، تأكَّد من تفعيل البريد الإلكتروني/كلمة المرور كمقدّم خدمة تسجيل الدخول في وحدة تحكّم Firebase.
    معاينة التطبيق

    لقطة شاشة لهذه الخطوة

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

    لقطة شاشة لهذه الخطوة

إضافة حالة المصادقة إلى واجهة المستخدم

بعد ذلك، تأكَّد من أنّ واجهة المستخدم تشير إلى أنّك مسجّل الدخول.

ستستخدم دالة الاستدعاء الخاصة بمراقب حالة مصادقة Firebase، والتي يتم إعلامها عند تغيير حالة تسجيل دخول المستخدم. إذا كان هناك مستخدم سجّل الدخول حاليًا، سيبدّل تطبيقك زر "تأكيد الحضور" إلى زر "تسجيل الخروج".

  1. في StackBlitz، انتقِل إلى ملف index.js.
  2. في أعلى الصفحة، ابحث عن عبارة الاستيراد 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';
    
  3. أضِف الرمز التالي في أسفل دالة main():
    async function main() {
      // ...
    
      // Listen to the current Auth state
      onAuthStateChanged(auth, user => {
        if (user) {
          startRsvpButton.textContent = 'LOGOUT';
        } else {
          startRsvpButton.textContent = 'RSVP';
        }
      });
    }
    main();
    
  4. في مستمع الزر، تحقَّق ممّا إذا كان هناك مستخدم حالي وقم بتسجيل خروجه. لإجراء ذلك، استبدِل الرمز 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);
      }
    });
    

من المفترض أن يعرض الزر في تطبيقك الآن تسجيل الخروج، ومن المفترض أن يعود إلى RSVP عند النقر عليه.

معاينة التطبيق

لقطة شاشة لهذه الخطوة

7- كتابة الرسائل في Cloud Firestore

من الرائع معرفة أنّ المستخدمين سيزورون تطبيقك، ولكن لنقدّم للضيوف نشاطًا آخر في التطبيق. ماذا لو كان بإمكانهم ترك رسائل في دفتر ضيوف؟ يمكنهم مشاركة سبب حماسهم للحضور أو الأشخاص الذين يأملون مقابلتهم.

لتخزين رسائل المحادثة التي يكتبها المستخدمون في التطبيق، ستستخدم Cloud Firestore.

نموذج البيانات

‫Cloud Firestore هي قاعدة بيانات NoSQL، ويتم تقسيم البيانات المخزّنة في قاعدة البيانات إلى مجموعات ومستندات وحقول ومجموعات فرعية. ستخزِّن كل رسالة من المحادثة كمستند في مجموعة من المستوى الأعلى تُسمى guestbook.

رسم بياني لنموذج بيانات Firestore يعرض مجموعة دفتر ضيوف تتضمّن مستندات رسائل متعددة

إضافة رسائل إلى Firestore

في هذا القسم، ستضيف وظيفة للمستخدمين لكتابة رسائل جديدة في قاعدة البيانات. أولاً، تضيف رمز HTML لعناصر واجهة المستخدم (حقل الرسالة وزر الإرسال). بعد ذلك، تضيف الرمز الذي يربط هذه العناصر بقاعدة البيانات.

لإضافة عناصر واجهة المستخدم لحقل الرسالة وزر الإرسال:

  1. في StackBlitz، انتقِل إلى ملف index.html.
  2. حدِّد موضع 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.

  1. في StackBlitz، انتقِل إلى ملف index.js.
  2. في أعلى الصفحة، ابحث عن عبارة الاستيراد 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';
    
  3. سنحفظ الآن مرجعًا إلى عنصر db في Firestore بعد initializeApp مباشرةً:
    initializeApp(firebaseConfig);
    auth = getAuth();
    db = getFirestore();
    
  4. في أسفل الدالة main()، أضِف الرمز التالي.

    يُرجى العِلم أنّ auth.currentUser.uid هو إشارة إلى المعرّف الفريد الذي يتم إنشاؤه تلقائيًا والذي تمنحه Firebase Authentication لجميع المستخدمين الذين سجّلوا الدخول.
    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. (تتوفّر مزيد من المعلومات عن قواعد الأمان لاحقًا في ورشة رموز البرامج).

  1. في StackBlitz، انتقِل إلى ملف index.js.
  2. عدِّل المستمع 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';
      }
    });
    

اختبار إرسال الرسائل

  1. تأكَّد من تسجيل الدخول إلى التطبيق.
  2. أدخِل رسالة، مثل "مرحبًا"، ثم انقر على إرسال.

يُسجِّل هذا الإجراء الرسالة في قاعدة بيانات Cloud Firestore. ومع ذلك، لن تظهر لك الرسالة في تطبيق الويب الفعلي لأنّك لا تزال بحاجة إلى تنفيذ استرداد البيانات. ستنفّذ ذلك في الخطوة التالية.

ولكن يمكنك الاطّلاع على الرسالة التي تمت إضافتها حديثًا في وحدة تحكّم Firebase.

في وحدة تحكُّم Firebase، في لوحة بيانات قاعدة بيانات Firestore، من المفترض أن تظهر لك مجموعة guestbook التي تتضمّن رسالتك التي أضفتها حديثًا. إذا واصلت إرسال الرسائل، ستتضمّن مجموعة دفتر الضيوف العديد من المستندات، مثل:

وحدة تحكُّم Firebase

لقطة شاشة لهذه الخطوة

8- قراءة الرسائل

مزامنة الرسائل

من الرائع أنّه يمكن للضيوف كتابة رسائل في قاعدة البيانات، ولكن لا يمكنهم الاطّلاع عليها في التطبيق بعد.

لعرض الرسائل، عليك إضافة مستمعين يتم تفعيلهم عند تغيير البيانات، ثم إنشاء عنصر واجهة مستخدم يعرض الرسائل الجديدة.

ستضيف رمزًا يستمع إلى الرسائل المُضافة حديثًا من التطبيق. أولاً، أضِف قسمًا في HTML لعرض الرسائل:

  1. في StackBlitz، انتقِل إلى ملف index.html.
  2. في guestbook-container، أضِف قسمًا جديدًا بمعرّف guestbook.
    <!-- ... -->
    
      <section id="guestbook-container">
       <h2>Discussion</h2>
    
       <form><!-- ... --></form>
    
       <section id="guestbook"></section>
    
     </section>
    
    <!-- ... -->
    

بعد ذلك، سجِّل المستمع الذي يستمع إلى التغييرات التي يتم إجراؤها على البيانات:

  1. في StackBlitz، انتقِل إلى ملف index.js.
  2. في أعلى الصفحة، ابحث عن عبارة الاستيراد firebase/firestore، ثم أضِف query وorderBy وonSnapshot، على النحو التالي:
    // ...
    import {
      getFirestore,
      addDoc,
      collection,
      query,
      orderBy,
      onSnapshot
    } from 'firebase/firestore';
    
  3. في أسفل دالة 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:

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

لقطة شاشة لهذه الخطوة

تحديد المجموعات

أولاً، حدِّد المجموعات التي يكتب التطبيق البيانات فيها.

  1. احذف عبارة match /{document=**} الحالية، لتظهر قواعدك على النحو التالي:
    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
      }
    }
    
  2. في 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.
      }
    }
    

إضافة قواعد الأمان

بما أنّك استخدمت معرّف Authenticate UID كحقل في كل مستند من دفاتر الضيوف، يمكنك الحصول على معرّف Authenticate UID والتأكّد من أنّ أي مستخدم يحاول الكتابة في المستند لديه معرّف Authenticate UID مطابق.

  1. أضِف قواعد القراءة والكتابة إلى مجموعة القواعد كما هو موضّح أدناه:
    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;
        }
      }
    }
    
  2. انقر على نشر لنشر القواعد الجديدة.في دفتر الضيوف، يمكن للمستخدمين الذين سجّلوا الدخول فقط قراءة الرسائل (أي رسالة)، ولكن لا يمكنك إنشاء رسالة إلا باستخدام رقم تعريف المستخدم. لا نسمح أيضًا بتعديل الرسائل أو حذفها.

إضافة قواعد التحقّق

  1. أضِف عملية التحقّق من البيانات للتأكّد من توفّر جميع الحقول المتوقّعة في المستند:
    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;
        }
      }
    }
    
  2. انقر على نشر لنشر القواعد الجديدة.

إعادة ضبط أدوات معالجة الأحداث

بما أنّ تطبيقك لا يسمح الآن إلا للمستخدمين الذين تمّت مصادقتهم بتسجيل الدخول، عليك نقل طلب البحث عن دفتر الضيوف firestore داخل مستمع المصادقة. بخلاف ذلك، ستظهر أخطاء في الأذونات وستتم إغلاق التطبيق عند تسجيل خروج المستخدم.

  1. في StackBlitz، انتقِل إلى ملف index.js.
  2. سحب مستمع مجموعة دفتر الضيف 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);
        });
      });
    }
    
  3. أضِف دالة جديدة تحتها باسم unsubscribeGuestbook. تحقَّق ممّا إذا كان المتغيّر guestbookListener غير فارغ، ثم استخدِم الدالة لإلغاء المستمع.
    // ...
    // Unsubscribe from guestbook updates
    function unsubscribeGuestbook() {
      if (guestbookListener != null) {
        guestbookListener();
        guestbookListener = null;
      }
    }
    

أخيرًا، أضِف الدوالّ الجديدة إلى دالة onAuthStateChanged callback.

  1. أضِف subscribeGuestbook() في أسفل if (user).
  2. أضِف 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- خطوة إضافية: تطبيق ما تعلمته

تسجيل حالة تأكيد حضور أحد الضيوف

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

ستضيف زرًّا للتبديل لتسجيل الأشخاص الذين يريدون حضور الحدث، ثم تجمع عدد المشاركين.

  1. في StackBlitz، انتقِل إلى ملف index.html.
  2. في 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>
    <!-- ... -->
    

معاينة التطبيق

لقطة شاشة لهذه الخطوة

بعد ذلك، سجِّل المستمع للنقرات على الأزرار. إذا نقر المستخدم على نعم، استخدِم معرّف المستخدم في المصادقة لحفظ الاستجابة في قاعدة البيانات.

  1. في StackBlitz، انتقِل إلى ملف index.js.
  2. في أعلى الصفحة، ابحث عن عبارة الاستيراد 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';
    
  3. في أسفل الدالة main()، أضِف الرمز البرمجي التالي للاستماع إلى حالة الردّ على الدعوة:
    async function main() {
      // ...
    
      // Listen to RSVP responses
      rsvpYes.onclick = async () => {
      };
      rsvpNo.onclick = async () => {
      };
    }
    main();
    
    
  4. بعد ذلك، أنشئ مجموعة جديدة باسم 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.

  1. بالنسبة إلى مجموعة attendees، بما أنّك استخدمت معرّف UID للمصادقة كاسم المستند، يمكنك الحصول عليه والتأكّد من أنّ 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;
        }
      }
    }
    
  2. انقر على نشر لنشر القواعد الجديدة.

إضافة قواعد التحقّق

  1. أضِف بعض قواعد التحقّق من صحة البيانات للتأكّد من توفّر جميع الحقول المتوقّعة في المستند:
    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;
    
        }
      }
    }
    
  2. لا تنسَ النقر على نشر لنشر قواعدك.

(اختياري) يمكنك الآن الاطّلاع على نتائج النقر على الأزرار. انتقِل إلى لوحة بيانات Cloud Firestore في وحدة تحكُّم Firebase.

قراءة حالة الردّ على الدعوة

بعد تسجيل الردود، لنلقِ نظرة على الحضور ونعرضه في واجهة المستخدم.

  1. في StackBlitz، انتقِل إلى ملف index.html.
  2. في description-container، أضِف عنصرًا جديدًا بمعرّف number-attending.
    <!-- ... -->
    
     <section id="description-container">
         <!-- ... -->
         <p id="number-attending"></p>
     </section>
    
    <!-- ... -->
    

بعد ذلك، سجِّل المستمع لمجموعة attendees واحتسِب عدد الردود نعم:

  1. في StackBlitz، انتقِل إلى ملف index.js.
  2. في أسفل دالة main()، أضِف الرمز التالي للاستماع إلى حالة RSVP واحتساب عدد النقرات على نعم.
    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();
    

أخيرًا، لنبرز الزر المقابل للحالة الحالية.

  1. أنشئ دالة تتحقّق مما إذا كان معرّف المستخدم الحالي للمصادقة يتضمّن إدخالًا في مجموعة 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';
          }
        }
      });
    }
    
  2. لننشئ أيضًا دالة لإلغاء الاشتراك. سيتم استخدام هذا الإجراء عندما يسجّل المستخدم الخروج.
    // ...
    function unsubscribeCurrentRSVP() {
      if (rsvpListener != null) {
        rsvpListener();
        rsvpListener = null;
      }
      rsvpYes.className = '';
      rsvpNo.className = '';
    }
    
  3. استدعاء الدوالّ من مستمع المصادقة
    // ...
    // 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();
        }
      });
    
  4. حاوِل تسجيل الدخول بصفتك مستخدمين متعدّدين ولاحظ زيادة العدد مع كل نقرة إضافية على الزر نعم.

معاينة التطبيق

لقطة شاشة لهذه الخطوة

11- تهانينا!

لقد استخدمت Firebase لإنشاء تطبيق ويب تفاعلي في الوقت الفعلي.

المواضيع التي تناولناها

  • مصادقة Firebase
  • FirebaseUI
  • Cloud Firestore
  • قواعد أمان Firebase

الخطوات التالية

  • هل تريد معرفة المزيد عن سير عمل المطوّرين في Firebase؟ اطّلِع على Codelab الخاص بمحاكي Firebase للتعرّف على كيفية اختبار تطبيقك وتشغيله بالكامل على الجهاز.
  • هل تريد الاطّلاع على مزيد من المعلومات عن منتجات Firebase الأخرى؟ هل تريد تخزين ملفات الصور التي يحمّلها المستخدمون؟ هل تريد إرسال إشعارات إلى المستخدمين؟ اطّلِع على مختبر رموز Firebase للويب للاطّلاع على مختبر رموز يتناول بالتفصيل العديد من منتجات Firebase للويب.
  • هل تريد معرفة المزيد من المعلومات عن Cloud Firestore؟ هل تريد الاطّلاع على معلومات عن المجموعات الفرعية والمعاملات؟ انتقِل إلى الدرس التطبيقي حول ترميز تطبيقات الويب في Cloud Firestore للحصول على درس تطبيقي يتناول بالتفصيل Cloud Firestore. يمكنك أيضًا الاطّلاع على سلسلة فيديوهات على YouTube للتعرّف على Cloud Firestore.

مزيد من المعلومات

كيف كانت النتيجة؟

يسرّنا تلقّي ملاحظاتك. يُرجى ملء نموذج قصير جدًا هنا.