تعرف على Firebase للويب

1. نظرة عامة

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

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

ما ستتعلمه

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

ماذا ستحتاج

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

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 Analytics، انقر فوق "عدم التمكين"، لأنك لن تستخدم Analytics لهذا التطبيق.

لمعرفة المزيد حول مشاريع Firebase، راجع فهم مشاريع Firebase .

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

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

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

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

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

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

  1. في اللوحة اليمنى لوحدة تحكم Firebase، انقر فوق Build > Authentication . ثم انقر فوق البدء . أنت الآن في لوحة معلومات المصادقة، حيث يمكنك رؤية المستخدمين المسجلين، وتكوين موفري تسجيل الدخول، وإدارة الإعدادات.

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

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

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

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

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

قم بإعداد Cloud Firestore

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

إليك كيفية إعداد Cloud Firestore:

  1. في اللوحة اليمنى لوحدة تحكم Firebase، انقر فوق Build > Firestore Database . ثم انقر فوق إنشاء قاعدة بيانات .
  2. انقر فوق إنشاء قاعدة بيانات .

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

  3. حدد خيار البدء في وضع الاختبار . اقرأ إخلاء المسؤولية حول قواعد الأمان. يضمن وضع الاختبار إمكانية الكتابة بحرية إلى قاعدة البيانات أثناء التطوير. انقر فوق {التالي .

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

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

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

  5. انقر فوق تم .

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. سجل التطبيق بالاسم المستعار Web App .
  4. بالنسبة لهذا الدرس التطبيقي حول التعليمات البرمجية، لا تحدد المربع الموجود بجوار إعداد Firebase Hosting لهذا التطبيق أيضًا . ستستخدم جزء المعاينة في 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.appspot.com",
      messagingSenderId: "random-unique-string",
      appId: "random-unique-string",
    };
    
    // Initialize Firebase
    initializeApp(firebaseConfig);
    

6. إضافة تسجيل دخول المستخدم (RSVP)

الآن بعد أن قمت بإضافة Firebase إلى التطبيق، يمكنك إعداد زر RSVP الذي يقوم بتسجيل الأشخاص باستخدام Firebase Authentication .

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

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

يتطلب FirebaseUI تكوينًا (راجع الخيارات الموجودة في الوثائق ) يقوم بأمرين:

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

أضف الرمز لتهيئة 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();
    
    

أضف زر RSVP إلى HTML

  1. في StackBlitz، انتقل إلى ملف index.html .
  2. أضف HTML لزر RSVP داخل 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، انقر فوق زر الرد على الدعوة لتسجيل الدخول إلى التطبيق.
    • في هذا الدرس التطبيقي حول الترميز، يمكنك استخدام أي عنوان بريد إلكتروني، حتى لو كان عنوان بريد إلكتروني مزيفًا، نظرًا لأنك لا تقوم بإعداد خطوة التحقق من البريد الإلكتروني لهذا الدرس التطبيقي حول الترميز.
    • إذا ظهرت لك رسالة خطأ تفيد بأن 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);
      }
    });
    

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

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

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

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. سنقوم الآن بحفظ مرجع إلى كائن Firestore db مباشرةً بعد initializeApp :
    initializeApp(firebaseConfig);
    auth = getAuth();
    db = getFirestore();
    
  4. في أسفل الدالة 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 Security Rules . (يوجد المزيد من المعلومات حول قواعد الأمان لاحقًا في الدرس التطبيقي حول التعليمات البرمجية.)

  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 Database ، ثم حدد علامة التبويب "القواعد " (أو انقر هنا للانتقال مباشرةً إلى علامة التبويب "القواعد" ).
  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.
      }
    }
    

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

نظرًا لأنك استخدمت معرف المصادقة الفريد (UID) كحقل في كل مستند سجل زوار، يمكنك الحصول على معرف المصادقة الفريد (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 .

    يعرض مستمع Firestore onSnapshot وظيفة إلغاء الاشتراك التي ستتمكن من استخدامها لإلغاء مستمع اللقطة لاحقًا.
    // ...
    // 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 .

  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>
    <!-- ... -->
    

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

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

بعد ذلك، قم بتسجيل المستمع لنقرات الزر. إذا قام المستخدم بالنقر فوق YES ، فاستخدم معرف المصادقة الفريد الخاص به لحفظ الاستجابة في قاعدة البيانات.

  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() ، أضف الكود التالي للاستماع إلى حالة الرد على الدعوة واحتساب النقرات بنعم .
    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. قم بإنشاء وظيفة تتحقق مما إذا كان معرف المصادقة الفريد (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';
          }
        }
      });
    }
    
  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
  • سحابة فايرستور
  • قواعد أمان Firebase

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

يتعلم أكثر

كيف سار الأمر؟

نحن نحب ملاحظاتك! يرجى ملء استمارة قصيرة (جدا) هنا .