مختبر برمجة الويب AngularFire

1. نظرة عامة

في هذا الدرس التطبيقي حول التعليمات البرمجية، ستتعلم كيفية استخدام AngularFire لإنشاء تطبيقات الويب من خلال تنفيذ ونشر عميل الدردشة باستخدام منتجات وخدمات Firebase.

angularfire-2.png

ما ستتعلمه

  • أنشئ تطبيق ويب باستخدام Angular وFirebase.
  • مزامنة البيانات باستخدام Cloud Firestore وCloud Storage for Firebase.
  • قم بمصادقة المستخدمين لديك باستخدام مصادقة Firebase.
  • انشر تطبيق الويب الخاص بك على استضافة Firebase.
  • إرسال الإشعارات باستخدام Firebase Cloud Messaging.
  • اجمع بيانات أداء تطبيق الويب الخاص بك.

ماذا ستحتاج

  • محرر IDE/النصوص الذي تختاره، مثل WebStorm أو Atom أو Sublime أو VS Code
  • مدير الحزم npm ، والذي يأتي عادةً مع Node.js
  • محطة/وحدة التحكم
  • متصفح من اختيارك، مثل Chrome
  • نموذج التعليمات البرمجية الخاص ببرنامج Codelab (راجع الخطوة التالية من برنامج Codelab للتعرف على كيفية الحصول على التعليمات البرمجية.)

2. احصل على نموذج التعليمات البرمجية

قم باستنساخ مستودع GitHub الخاص بـ Codelab من سطر الأوامر:

git clone https://github.com/firebase/codelab-friendlychat-web

وبدلاً من ذلك، إذا لم يكن git مثبتًا لديك، فيمكنك تنزيل المستودع كملف ZIP .

قم باستيراد تطبيق البداية

باستخدام IDE الخاص بك، افتح أو استورد دليل 📁 angularfire-start من المستودع المستنسخ. يحتوي دليل 📁 angularfire-start هذا على رمز البداية لـ Codelab، والذي سيكون تطبيق ويب للدردشة يعمل بكامل طاقته.

3. إنشاء وإعداد مشروع Firebase

إنشاء مشروع Firebase

  1. قم بتسجيل الدخول إلى Firebase .
  2. في وحدة تحكم Firebase، انقر فوق "إضافة مشروع" ثم قم بتسمية مشروع Firebase FriendlyChat . تذكر معرف المشروع لمشروع Firebase الخاص بك.
  3. قم بإلغاء تحديد تمكين Google Analytics لهذا المشروع
  4. انقر فوق إنشاء مشروع .

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

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

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

أضف تطبيق ويب Firebase إلى المشروع

  1. انقر على أيقونة الويب 58d6543a156e56f9.png لإنشاء تطبيق ويب Firebase جديد.
  2. قم بتسجيل التطبيق بالاسم المستعار Friendly Chat ، ثم حدد المربع بجوار إعداد Firebase Hosting لهذا التطبيق أيضًا . انقر فوق تسجيل التطبيق .
  3. في الخطوة التالية، سترى كائن التكوين. انسخ كائن JS فقط (وليس HTML المحيط) إلى firebase-config.js

تسجيل لقطة شاشة لتطبيق الويب

تمكين تسجيل الدخول إلى Google لمصادقة Firebase

للسماح للمستخدمين بتسجيل الدخول إلى تطبيق الويب باستخدام حسابات Google الخاصة بهم، ستستخدم طريقة تسجيل الدخول إلى Google .

ستحتاج إلى تمكين تسجيل الدخول إلى Google :

  1. في وحدة تحكم Firebase، حدد موقع قسم البناء في اللوحة اليمنى.
  2. انقر فوق "المصادقة" ، ثم انقر فوق علامة التبويب "طريقة تسجيل الدخول " (أو انقر هنا للانتقال مباشرة إلى هناك).
  3. قم بتمكين موفر تسجيل الدخول إلى Google ، ثم انقر فوق "حفظ" .
  4. قم بتعيين الاسم العام لتطبيقك على الدردشة الودية واختر بريدًا إلكترونيًا لدعم المشروع من القائمة المنسدلة.
  5. قم بتكوين شاشة موافقة OAuth في Google Cloud Console وأضف شعارًا:

d89fb3873b5d36ae.png

تمكين سحابة Firestore

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

ستحتاج إلى تمكين Cloud Firestore:

  1. في قسم الإنشاء بوحدة تحكم Firebase، انقر فوق Firestore Database .
  2. انقر فوق إنشاء قاعدة بيانات في جزء Cloud Firestore.

729991a081e7cd5.png

  1. حدد خيار البدء في وضع الاختبار ، ثم انقر فوق التالي بعد قراءة إخلاء المسؤولية حول قواعد الأمان.

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

77e4986cbeaf9dee.png

  1. قم بتعيين الموقع حيث يتم تخزين بيانات Cloud Firestore الخاصة بك. يمكنك ترك هذا كإعداد افتراضي أو اختيار منطقة قريبة منك. انقر فوق تم لتوفير Firestore.

9f2bb0d4e7ca49c7.png

تمكين التخزين السحابي

يستخدم تطبيق الويب Cloud Storage for Firebase لتخزين الصور وتحميلها ومشاركتها.

ستحتاج إلى تمكين التخزين السحابي:

  1. في قسم الإنشاء بوحدة تحكم Firebase، انقر فوق التخزين .
  2. إذا لم يكن هناك زر البدء ، فهذا يعني أن التخزين السحابي ممكّن بالفعل، ولن تحتاج إلى اتباع الخطوات أدناه.
  3. انقر فوق البدء .
  4. اقرأ إخلاء المسؤولية حول قواعد الأمان لمشروع Firebase الخاص بك، ثم انقر على "التالي" .

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

62f1afdcd1260127.png

  1. يتم تحديد موقع Cloud Storage مسبقًا بنفس المنطقة التي اخترتها لقاعدة بيانات Cloud Firestore الخاصة بك. انقر فوق تم لإكمال الإعداد.

1d7f49ebaddb32fc.png

4. قم بتثبيت واجهة سطر أوامر Firebase

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

  1. قم بتثبيت واجهة سطر الأوامر (CLI) عن طريق تشغيل الأمر npm التالي:
npm -g install firebase-tools
  1. تحقق من تثبيت واجهة سطر الأوامر (CLI) بشكل صحيح عن طريق تشغيل الأمر التالي:
firebase --version

تأكد من أن إصدار Firebase CLI هو v4.1.0 أو إصدار أحدث.

  1. قم بتخويل Firebase CLI عن طريق تشغيل الأمر التالي:
firebase login

لقد قمت بإعداد قالب تطبيق الويب لسحب تكوين تطبيقك لاستضافة Firebase من الدليل المحلي لتطبيقك (المستودع الذي قمت باستنساخه مسبقًا في Codelab). ولكن لسحب التكوين، تحتاج إلى ربط تطبيقك بمشروع Firebase الخاص بك.

  1. تأكد من أن سطر الأوامر الخاص بك يصل إلى دليل angularfire-start المحلي لتطبيقك.
  2. قم بربط تطبيقك بمشروع Firebase الخاص بك عن طريق تشغيل الأمر التالي:
firebase use --add
  1. عند المطالبة، حدد معرف المشروع الخاص بك، ثم قم بإعطاء مشروع Firebase الخاص بك اسمًا مستعارًا.

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

  1. اتبع التعليمات المتبقية في سطر الأوامر الخاص بك.

5. قم بتثبيت AngularFire

قبل تشغيل المشروع، تأكد من إعداد Angular CLI وAngularFire.

  1. في وحدة التحكم، قم بتشغيل الأمر التالي:
npm install -g @angular/cli
  1. بعد ذلك، في وحدة التحكم من دليل angularfire-start ، قم بتشغيل أمر Angular CLI التالي:
ng add @angular/fire

سيؤدي هذا إلى تثبيت كافة التبعيات اللازمة لمشروعك.

  1. عندما يُطلب منك ذلك، حدد الميزات التي تم إعدادها في وحدة تحكم Firebase ( ng deploy -- hosting , Authentication , Firestore , Cloud Functions (callable) , Cloud Messaging , Cloud Storage )، واتبع المطالبات الموجودة على وحدة التحكم.

6. قم بتشغيل تطبيق البداية محليًا

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

  1. في وحدة التحكم من دليل angularfire-start ، قم بتشغيل أمر Firebase CLI التالي:
firebase emulators:start
  1. يجب أن يعرض سطر الأوامر الاستجابة التالية:
✔  hosting: Local server: http://localhost:5000

أنت تستخدم محاكي Firebase Hosting لخدمة تطبيقنا محليًا. يجب أن يكون تطبيق الويب متاحًا الآن من http://localhost:5000 . يتم تقديم جميع الملفات الموجودة ضمن الدليل الفرعي src .

  1. باستخدام متصفحك، افتح تطبيقك على http://localhost:5000 .

من المفترض أن تشاهد واجهة المستخدم الخاصة بتطبيق FriendlyChat، والتي لا تعمل (حتى الآن):

angularfire-2.png

لا يستطيع التطبيق فعل أي شيء في الوقت الحالي، ولكن بمساعدتك، سوف يفعله قريبًا! لقد قمت فقط بوضع واجهة المستخدم لك حتى الآن.

دعونا الآن نبني دردشة في الوقت الحقيقي!

7. استيراد وتكوين Firebase

تكوين Firebase

ستحتاج إلى تكوين Firebase SDK لإخبارها بمشروع Firebase الذي تستخدمه.

  1. انتقل إلى إعدادات المشروع في وحدة تحكم Firebase
  2. في بطاقة "تطبيقاتك"، حدد لقب التطبيق الذي تحتاج إلى كائن تكوين له.
  3. حدد "التكوين" من جزء مقتطف Firebase SDK.

ستجد أنه تم إنشاء ملف بيئة /angularfire-start/src/environments/environment.ts لك.

  1. انسخ مقتطف كائن التكوين، ثم أضفه إلى angularfire-start/src/firebase-config.js .

environment.ts

export const environment = {
  firebase: {
    apiKey: "API_KEY",
    authDomain: "PROJECT_ID.firebaseapp.com",
    databaseURL: "https://PROJECT_ID.firebaseio.com",
    projectId: "PROJECT_ID",
    storageBucket: "PROJECT_ID.appspot.com",
    messagingSenderId: "SENDER_ID",
    appId: "APP_ID",
    measurementId: "G-MEASUREMENT_ID",
  },
};

استيراد أنجولار فاير

ستجد أن الميزات التي حددتها في وحدة التحكم تم توجيهها تلقائيًا في الملف /angularfire-start/src/app/app.module.ts . يتيح ذلك لتطبيقك استخدام ميزات ووظائف Firebase. ومع ذلك، للتطوير في بيئة محلية، تحتاج إلى توصيلها لاستخدام مجموعة Emulator.

  1. في /angularfire-start/src/app/app.module.ts ، ابحث عن قسم imports ، وقم بتعديل الوظائف المتوفرة للاتصال بمجموعة Emulator في البيئات غير الإنتاجية.
// ...

import { provideAuth,getAuth, connectAuthEmulator } from '@angular/fire/auth';
import { provideFirestore,getFirestore, connectFirestoreEmulator } from '@angular/fire/firestore';
import { provideFunctions,getFunctions, connectFunctionsEmulator } from '@angular/fire/functions';
import { provideMessaging,getMessaging } from '@angular/fire/messaging';
import { provideStorage,getStorage, connectStorageEmulator } from '@angular/fire/storage';

// ...

provideFirebaseApp(() => initializeApp(environment.firebase)),
provideAuth(() => {
    const auth = getAuth();
    if (location.hostname === 'localhost') {
        connectAuthEmulator(auth, 'http://127.0.0.1:9099', { disableWarnings: true });
    }
    return auth;
}),
provideFirestore(() => {
    const firestore = getFirestore();
    if (location.hostname === 'localhost') {
        connectFirestoreEmulator(firestore, '127.0.0.1', 8080);
    }
    return firestore;
}),
provideFunctions(() => {
    const functions = getFunctions();
    if (location.hostname === 'localhost') {
        connectFunctionsEmulator(functions, '127.0.0.1', 5001);
    }
    return functions;
}),
provideStorage(() => {
    const storage = getStorage();
    if (location.hostname === 'localhost') {
        connectStorageEmulator(storage, '127.0.0.1', 5001);
    }
    return storage;
}),
provideMessaging(() => {
    return getMessaging();
}),

// ...

app.module.ts

خلال هذا الدرس التطبيقي حول التعليمات البرمجية، ستستخدم مصادقة Firebase، وCloud Firestore، وCloud Storage، وCloud Messaging، ومراقبة الأداء، بحيث تقوم باستيراد جميع مكتباتها. في تطبيقاتك المستقبلية، تأكد من أنك تستورد فقط أجزاء Firebase التي تحتاجها، لتقصير وقت تحميل تطبيقك.

8. قم بإعداد تسجيل دخول المستخدم

يجب أن يكون AngularFire الآن جاهزًا للاستخدام نظرًا لأنه تم استيراده وتهيئته في app.module.ts . ستقوم الآن بتنفيذ تسجيل دخول المستخدم باستخدام مصادقة Firebase .

قم بمصادقة المستخدمين لديك من خلال تسجيل الدخول بحساب Google

في التطبيق، عندما ينقر المستخدم على زر تسجيل الدخول باستخدام Google ، يتم تشغيل وظيفة login . (لقد قمت بالفعل بإعداد ذلك لك!) بالنسبة لهذا الدرس التطبيقي حول الترميز، فإنك تريد السماح لـ Firebase باستخدام Google كموفر للهوية. ستستخدم نافذة منبثقة، ولكن تتوفر عدة طرق أخرى من Firebase.

  1. في الدليل angularfire-start ، في الدليل الفرعي /src/app/services/ ، افتح chat.service.ts .
  2. ابحث عن وظيفة login .
  3. استبدل الدالة بأكملها بالكود التالي.

chat.service.ts

// Signs-in Friendly Chat.
login() {
    signInWithPopup(this.auth, this.provider).then((result) => {
        const credential = GoogleAuthProvider.credentialFromResult(result);
        this.router.navigate(['/', 'chat']);
        return credential;
    })
}

يتم تشغيل وظيفة logout عندما ينقر المستخدم على زر تسجيل الخروج .

  1. ارجع إلى الملف src/app/services/chat.service.ts .
  2. ابحث عن وظيفة logout .
  3. استبدل الدالة بأكملها بالكود التالي.

chat.service.ts

// Logout of Friendly Chat.
logout() {
    signOut(this.auth).then(() => {
        this.router.navigate(['/', 'login'])
        console.log('signed out');
    }).catch((error) => {
        console.log('sign out error: ' + error);
    })
}

تتبع حالة المصادقة

لتحديث واجهة المستخدم الخاصة بنا وفقًا لذلك، تحتاج إلى طريقة للتحقق مما إذا كان المستخدم قد قام بتسجيل الدخول أو الخروج. باستخدام مصادقة Firebase، يمكنك استرداد حالة المستخدم التي يمكن ملاحظتها والتي سيتم تشغيلها في كل مرة تتغير فيها حالة المصادقة.

  1. ارجع إلى الملف src/app/services/chat.service.ts .
  2. ابحث عن المتغير المخصص user$ .
  3. استبدل المهمة بأكملها بالكود التالي.

chat.service.ts

// Observable user
user$ = user(this.auth);

يستدعي الكود أعلاه user وظيفة AngularFire الذي يقوم بإرجاع مستخدم يمكن ملاحظته. سيتم تشغيله في كل مرة تتغير فيها حالة المصادقة (عندما يقوم المستخدم بتسجيل الدخول أو الخروج). في هذه المرحلة ستقوم بتحديث واجهة المستخدم لإعادة التوجيه وعرض المستخدم في شريط التنقل في الرأس وما إلى ذلك. تم بالفعل تنفيذ جميع أجزاء واجهة المستخدم هذه.

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

  1. إذا كان تطبيقك لا يزال قيد العرض، فقم بتحديث تطبيقك في المتصفح. بخلاف ذلك، قم بتشغيل firebase emulators:start من سطر الأوامر لبدء خدمة التطبيق من http://localhost:5000 ، ثم افتحه في متصفحك.
  2. قم بتسجيل الدخول إلى التطبيق باستخدام زر تسجيل الدخول وحساب Google الخاص بك. إذا ظهرت لك رسالة خطأ تفيد auth/operation-not-allowed ، فتحقق للتأكد من تمكين تسجيل الدخول بحساب Google كموفر مصادقة في وحدة تحكم Firebase.
  3. بعد تسجيل الدخول، يجب أن يتم عرض صورة ملفك الشخصي واسم المستخدم: angularfire-3.png

9. اكتب الرسائل إلى Cloud Firestore

في هذا القسم، ستكتب بعض البيانات إلى Cloud Firestore حتى تتمكن من ملء واجهة المستخدم الخاصة بالتطبيق. يمكن القيام بذلك يدويًا باستخدام وحدة تحكم Firebase ، ولكنك ستفعل ذلك في التطبيق نفسه لإظهار الكتابة الأساسية لـ Cloud Firestore.

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

يتم تقسيم بيانات Cloud Firestore إلى مجموعات ومستندات وحقول ومجموعات فرعية. ستقوم بتخزين كل رسالة من رسائل الدردشة كمستند في مجموعة المستوى الأعلى تسمى messages .

688d7bc5fb662b57.png

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

لتخزين رسائل الدردشة التي يكتبها المستخدمون، عليك استخدام Cloud Firestore .

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

  1. ارجع إلى الملف src/app/services/chat.service.ts .
  2. ابحث عن الوظيفة addMessage .
  3. استبدل الدالة بأكملها بالكود التالي.

chat.service.ts

// Adds a text or image message to Cloud Firestore.
addMessage = async(textMessage: string | null, imageUrl: string | null): Promise<void | DocumentReference<DocumentData>> => {
    let data: any;
    try {
      this.user$.subscribe(async (user) => 
      { 
        if(textMessage && textMessage.length > 0) {
          data =  await addDoc(collection(this.firestore, 'messages'), {
            name: user?.displayName,
            text: textMessage,
            profilePicUrl: user?.photoURL,
            timestamp: serverTimestamp(),
            uid: user?.uid
          })}
          else if (imageUrl && imageUrl.length > 0) {
            data =  await addDoc(collection(this.firestore, 'messages'), {
              name: user?.displayName,
              imageUrl: imageUrl,
              profilePicUrl: user?.photoURL,
              timestamp: serverTimestamp(),
              uid: user?.uid
            });
          }
          return data;
        }
      );
    }
    catch(error) {
      console.error('Error writing new message to Firebase Database', error);
      return;
    }
}

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

  1. إذا كان تطبيقك لا يزال قيد العرض، فقم بتحديث تطبيقك في المتصفح. بخلاف ذلك، قم بتشغيل firebase emulators:start من سطر الأوامر لبدء خدمة التطبيق من http://localhost:5000 ، ثم افتحه في متصفحك.
  2. بعد تسجيل الدخول، أدخل رسالة مثل "مرحبًا!"، ثم انقر فوق إرسال . سيؤدي هذا إلى كتابة الرسالة في Cloud Firestore. ومع ذلك، لن تتمكن بعد من رؤية البيانات في تطبيق الويب الفعلي الخاص بك لأنك لا تزال بحاجة إلى تنفيذ استرداد البيانات (القسم التالي من الدرس التطبيقي حول التعليمات البرمجية).
  3. يمكنك رؤية الرسالة المضافة حديثًا في وحدة تحكم Firebase الخاصة بك. افتح واجهة مستخدم مجموعة المحاكي الخاصة بك. ضمن قسم الإنشاء ، انقر فوق Firestore Database (أو انقر هنا وسترى مجموعة الرسائل مع رسالتك المضافة حديثًا:

6812efe7da395692.png

10. قراءة الرسائل

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

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

ستضيف رمزًا يستمع إلى الرسائل المضافة حديثًا من التطبيق. في هذا الكود، سوف تقوم باسترداد لقطة من مجموعة messages . ستعرض فقط آخر 12 رسالة من الدردشة لتجنب عرض سجل طويل جدًا عند التحميل.

  1. ارجع إلى الملف src/app/services/chat.service.ts .
  2. ابحث عن الوظيفة loadMessages .
  3. استبدل الدالة بأكملها بالكود التالي.

chat.service.ts

// Loads chat message history and listens for upcoming ones.
loadMessages = () => {
  // Create the query to load the last 12 messages and listen for new ones.
  const recentMessagesQuery = query(collection(this.firestore, 'messages'), orderBy('timestamp', 'desc'), limit(12));
  // Start listening to the query.
  return collectionData(recentMessagesQuery);
}

للاستماع إلى الرسائل في قاعدة البيانات، يمكنك إنشاء استعلام على مجموعة باستخدام وظيفة collection لتحديد المجموعة التي توجد بها البيانات التي تريد الاستماع إليها. في الكود أعلاه، أنت تستمع إلى التغييرات داخل messages المجموعة، حيث يتم تخزين رسائل الدردشة. أنت أيضًا تطبق حدًا من خلال الاستماع فقط إلى آخر 12 رسالة باستخدام limit(12) وترتيب الرسائل حسب التاريخ باستخدام orderBy('timestamp', 'desc') للحصول على أحدث 12 رسالة.

تستخدم وظيفة collectionData لقطات تحت الغطاء. سيتم تشغيل وظيفة رد الاتصال عندما تكون هناك أية تغييرات على المستندات التي تطابق الاستعلام. قد يحدث هذا في حالة حذف رسالة أو تعديلها أو إضافتها. يمكنك قراءة المزيد حول هذا الأمر في وثائق Cloud Firestore .

اختبار مزامنة الرسائل

  1. إذا كان تطبيقك لا يزال قيد العرض، فقم بتحديث تطبيقك في المتصفح. بخلاف ذلك، قم بتشغيل firebase emulators:start من سطر الأوامر لبدء خدمة التطبيق من http://localhost:5000 ، ثم افتحه في متصفحك.
  2. يجب أن يتم عرض الرسائل التي قمت بإنشائها مسبقًا في قاعدة البيانات في واجهة مستخدم FriendlyChat (انظر أدناه). لا تتردد في كتابة رسائل جديدة. يجب أن تظهر على الفور.
  3. (اختياري) يمكنك محاولة حذف الرسائل الجديدة أو تعديلها أو إضافتها يدويًا مباشرةً في قسم Firestore في مجموعة Emulator؛ يجب أن تنعكس أي تغييرات في واجهة المستخدم.

تهانينا! أنت تقرأ مستندات Cloud Firestore في تطبيقك!

angularfire-2.png

11. إرسال الصور

ستضيف الآن ميزة تشارك الصور.

في حين أن Cloud Firestore مفيد لتخزين البيانات المنظمة، فإن Cloud Storage مناسب بشكل أفضل لتخزين الملفات. Cloud Storage for Firebase عبارة عن خدمة تخزين ملفات/كائنات كبيرة الحجم، وستستخدمها لتخزين أي صور يشاركها المستخدم باستخدام تطبيقنا.

حفظ الصور في التخزين السحابي

بالنسبة لهذا الدرس التطبيقي حول الترميز، لقد أضفت بالفعل زرًا لتشغيل مربع حوار منتقي الملفات. بعد تحديد ملف، يتم استدعاء وظيفة saveImageMessage ، ويمكنك الحصول على مرجع للملف المحدد. تقوم وظيفة saveImageMessage بما يلي:

  1. ينشئ رسالة دردشة "عنصرًا نائبًا" في موجز الدردشة، بحيث يرى المستخدمون رسمًا متحركًا "جارٍ التحميل" أثناء تحميل الصورة.
  2. يقوم بتحميل ملف الصورة إلى Cloud Storage إلى هذا المسار: /<uid>/<file_name>
  3. يُنشئ عنوان URL قابلاً للقراءة بشكل عام لملف الصورة.
  4. يقوم بتحديث رسالة الدردشة بعنوان URL لملف الصورة الذي تم تحميله حديثًا بدلاً من صورة التحميل المؤقتة.

ستضيف الآن وظيفة إرسال صورة:

  1. ارجع إلى الملف src/chat.service.ts .
  2. ابحث عن الوظيفة saveImageMessage .
  3. استبدل الدالة بأكملها بالكود التالي.

chat.service.ts

// Saves a new message containing an image in Firebase.
// This first saves the image in Firebase storage.
saveImageMessage = async(file: any) => {
  try {
    // 1 - You add a message with a loading icon that will get updated with the shared image.
    const messageRef = await this.addMessage(null, this.LOADING_IMAGE_URL);

    // 2 - Upload the image to Cloud Storage.
    const filePath = `${this.auth.currentUser?.uid}/${file.name}`;
    const newImageRef = ref(this.storage, filePath);
    const fileSnapshot = await uploadBytesResumable(newImageRef, file);
    
    // 3 - Generate a public URL for the file.
    const publicImageUrl = await getDownloadURL(newImageRef);

    // 4 - Update the chat message placeholder with the image's URL.
    messageRef ?
    await updateDoc(messageRef,{
      imageUrl: publicImageUrl,
      storageUri: fileSnapshot.metadata.fullPath
    }): null;
  } catch (error) {
    console.error('There was an error uploading a file to Cloud Storage:', error);
  }
}

اختبار إرسال الصور

  1. إذا كان تطبيقك لا يزال قيد العرض، فقم بتحديث تطبيقك في المتصفح. بخلاف ذلك، قم بتشغيل firebase emulators:start من سطر الأوامر لبدء خدمة التطبيق من http://localhost:5000 ، ثم افتحه في متصفحك.
  2. بعد تسجيل الدخول، انقر فوق زر تحميل الصورة في أسفل اليسار angularfire-4.png وحدد ملف صورة باستخدام منتقي الملفات. إذا كنت تبحث عن صورة، فلا تتردد في استخدام هذه الصورة الجميلة لفنجان القهوة .
  3. يجب أن تظهر رسالة جديدة في واجهة مستخدم التطبيق مع الصورة المحددة: angularfire-2.png

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

12. عرض الإخطارات

ستضيف الآن دعمًا لإشعارات المتصفح. سيقوم التطبيق بإعلام المستخدمين عند نشر رسائل جديدة في الدردشة. يعد Firebase Cloud Messaging (FCM) أحد حلول المراسلة عبر الأنظمة الأساسية التي تتيح لك تسليم الرسائل والإشعارات بشكل موثوق دون أي تكلفة.

إضافة عامل خدمة FCM

يحتاج تطبيق الويب إلى عامل خدمة يتلقى إشعارات الويب ويعرضها.

يجب أن يكون موفر المراسلة قد تم إعداده بالفعل عند إضافة AngularFire، تأكد من وجود الكود التالي في قسم الاستيراد في /angularfire-start/src/app/app.module.ts

provideMessaging(() => {
    return getMessaging();
}),

app/app.module.ts

يحتاج عامل الخدمة ببساطة إلى تحميل Firebase Cloud Messaging SDK وتهيئته، والذي سيهتم بعرض الإشعارات.

احصل على رموز جهاز FCM

عند تمكين الإشعارات على جهاز أو متصفح، سيتم منحك رمزًا مميزًا للجهاز . رمز الجهاز هذا هو ما تستخدمه لإرسال إشعار إلى جهاز معين أو متصفح معين.

عندما يقوم المستخدم بتسجيل الدخول، يمكنك استدعاء وظيفة saveMessagingDeviceToken . هذا هو المكان الذي ستحصل فيه على الرمز المميز لجهاز FCM من المتصفح وحفظه في Cloud Firestore.

chat.service.ts

  1. ابحث عن الوظيفة saveMessagingDeviceToken .
  2. استبدل الدالة بأكملها بالكود التالي.

chat.service.ts

// Saves the messaging device token to Cloud Firestore.
saveMessagingDeviceToken= async () => {
    try {
      const currentToken = await getToken(this.messaging);
      if (currentToken) {
        console.log('Got FCM device token:', currentToken);
        // Saving the Device Token to Cloud Firestore.
        const tokenRef = doc(this.firestore, 'fcmTokens', currentToken);
        await setDoc(tokenRef, { uid: this.auth.currentUser?.uid });
 
        // This will fire when a message is received while the app is in the foreground.
        // When the app is in the background, firebase-messaging-sw.js will receive the message instead.
        onMessage(this.messaging, (message) => {
          console.log(
            'New foreground notification from Firebase Messaging!',
            message.notification
          );
        });
      } else {
        // Need to request permissions to show notifications.
        this.requestNotificationsPermissions();
      }
    } catch(error) {
      console.error('Unable to get messaging token.', error);
    };
}

ومع ذلك، لن يعمل هذا الرمز في البداية. لكي يتمكن تطبيقك من استرداد الرمز المميز للجهاز، يحتاج المستخدم إلى منح تطبيقك الإذن لعرض الإشعارات (الخطوة التالية من الدرس التطبيقي حول التعليمات البرمجية).

طلب أذونات لإظهار الإخطارات

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

8b9d0c66dc36153d.png

  1. ارجع إلى الملف src/app/services/chat.service.ts .
  2. ابحث عن الوظيفة requestNotificationsPermissions .
  3. استبدل الدالة بأكملها بالكود التالي.

chat.service.ts

// Requests permissions to show notifications.
requestNotificationsPermissions = async () => {
    console.log('Requesting notifications permission...');
    const permission = await Notification.requestPermission();
    
    if (permission === 'granted') {
      console.log('Notification permission granted.');
      // Notification permission granted.
      await this.saveMessagingDeviceToken();
    } else {
      console.log('Unable to get permission to notify.');
    }
}

احصل على رمز جهازك

  1. إذا كان تطبيقك لا يزال قيد العرض، فقم بتحديث تطبيقك في المتصفح. بخلاف ذلك، قم بتشغيل firebase emulators:start من سطر الأوامر لبدء خدمة التطبيق من http://localhost:5000 ، ثم افتحه في متصفحك.
  2. بعد تسجيل الدخول، يجب أن يظهر مربع حوار إذن الإشعارات: bd3454e6dbfb6723.png
  3. انقر فوق السماح .
  4. افتح وحدة تحكم JavaScript في متصفحك. يجب أن تشاهد الرسالة التالية: Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
  5. انسخ الرمز المميز لجهازك. ستحتاج إليه في المرحلة التالية من الدرس التطبيقي حول الترميز.

إرسال إشعار إلى جهازك

الآن بعد أن أصبح لديك الرمز المميز لجهازك، يمكنك إرسال إشعار.

  1. افتح علامة التبويب Cloud Messaging في وحدة تحكم Firebase .
  2. انقر فوق "إشعار جديد"
  3. أدخل عنوان الإشعار ونص الإشعار.
  4. على الجانب الأيمن من الشاشة، انقر فوق "إرسال رسالة اختبارية"
  5. أدخل رمز الجهاز الذي نسخته من وحدة تحكم JavaScript في متصفحك، ثم انقر فوق علامة الجمع ("+").
  6. انقر فوق "اختبار"

إذا كان تطبيقك في المقدمة، فسترى الإشعار في وحدة تحكم JavaScript.

إذا كان تطبيقك في الخلفية، فيجب أن يظهر إشعار في متصفحك، كما في هذا المثال:

de79e8638a45864c.png

13. قواعد أمان Cloud Firestore

عرض قواعد أمان قاعدة البيانات

يستخدم Cloud Firestore لغة قواعد محددة لتحديد حقوق الوصول والأمان والتحقق من صحة البيانات.

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

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

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write;
    }
  }
}

ستقوم بتحديث القواعد لتقييد الأشياء باستخدام القواعد التالية:

firestore.rules

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    // Messages:
    //   - Anyone can read.
    //   - Authenticated users can add and edit messages.
    //   - Validation: Check name is same as auth token and text length below 300 char or that imageUrl is a URL.
    //   - Deletes are not allowed.
    match /messages/{messageId} {
      allow read;
      allow create, update: if request.auth != null
                    && request.resource.data.name == request.auth.token.name
                    && (request.resource.data.text is string
                      && request.resource.data.text.size() <= 300
                      || request.resource.data.imageUrl is string
                      && request.resource.data.imageUrl.matches('https?://.*'));
      allow delete: if false;
    }
    // FCM Tokens:
    //   - Anyone can write their token.
    //   - Reading list of tokens is not allowed.
    match /fcmTokens/{token} {
      allow read: if false;
      allow write;
    }
  }
}

يجب أن يتم تحديث قواعد الأمان تلقائيًا إلى مجموعة المحاكي الخاصة بك.

عرض قواعد أمان التخزين السحابي

يستخدم Cloud Storage for Firebase لغة قواعد محددة لتحديد حقوق الوصول والأمان والتحقق من صحة البيانات.

عند إعداد مشروع Firebase في بداية هذا الدرس التطبيقي حول الترميز، اخترت استخدام قاعدة أمان Cloud Storage الافتراضية التي تسمح فقط للمستخدمين المصادق عليهم باستخدام Cloud Storage. في وحدة تحكم Firebase ، في علامة التبويب "القواعد" بقسم التخزين ، يمكنك عرض القواعد وتعديلها. يجب أن تشاهد القاعدة الافتراضية التي تسمح لأي مستخدم قام بتسجيل الدخول بقراءة وكتابة أي ملفات في مجموعة التخزين الخاصة بك.

rules_version = '2';

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

ستقوم بتحديث القواعد للقيام بما يلي:

  • السماح لكل مستخدم بالكتابة فقط في المجلدات الخاصة به
  • السماح لأي شخص بالقراءة من التخزين السحابي
  • تأكد من أن الملفات التي تم تحميلها هي صور
  • تقييد حجم الصور التي يمكن تحميلها بحد أقصى 5 ميغابايت

ويمكن تنفيذ ذلك باستخدام القواعد التالية:

قواعد التخزين

rules_version = '2';

// Returns true if the uploaded file is an image and its size is below the given number of MB.
function isImageBelowMaxSize(maxSizeMB) {
  return request.resource.size < maxSizeMB * 1024 * 1024
      && request.resource.contentType.matches('image/.*');
}

service firebase.storage {
  match /b/{bucket}/o {
    match /{userId}/{messageId}/{fileName} {
      allow write: if request.auth != null && request.auth.uid == userId && isImageBelowMaxSize(5);
      allow read;
    }
  }
}

14. انشر تطبيقك باستخدام استضافة Firebase

يقدم Firebase خدمة استضافة لخدمة الأصول وتطبيقات الويب الخاصة بك. يمكنك نشر ملفاتك على Firebase Hosting باستخدام Firebase CLI. قبل النشر، يتعين عليك أن تحدد في ملف firebase.json الملفات المحلية التي يجب نشرها. بالنسبة إلى هذا الدرس التطبيقي حول الترميز، لقد قمت بذلك بالفعل نيابةً عنك لأن هذه الخطوة كانت مطلوبة لخدمة ملفاتنا أثناء هذا الدرس التطبيقي حول الترميز. يتم تحديد إعدادات الاستضافة ضمن سمة hosting :

firebase.json

{
  // If you went through the "Cloud Firestore Security Rules" step.
  "firestore": {
    "rules": "firestore.rules"
  },
  // If you went through the "Storage Security Rules" step.
  "storage": {
    "rules": "storage.rules"
  },
  "hosting": {
    "public": "./public"
  }
}

تخبر هذه الإعدادات واجهة سطر الأوامر (CLI) أنك تريد نشر جميع الملفات في الدليل ./public ( "public": "./public" ).

  1. تأكد من أن سطر الأوامر الخاص بك يصل إلى دليل angularfire-start المحلي لتطبيقك.
  2. انشر ملفاتك إلى مشروع Firebase الخاص بك عن طريق تشغيل الأمر التالي:
ng deploy

ثم حدد خيار Firebase، واتبع المطالبات الموجودة في سطر الأوامر.

  1. يجب أن تعرض وحدة التحكم ما يلي:
=== Deploying to 'friendlychat-1234'...

i  deploying firestore, storage, hosting
i  storage: checking storage.rules for compilation errors...
✔  storage: rules file storage.rules compiled successfully
i  firestore: checking firestore.rules for compilation errors...
✔  firestore: rules file firestore.rules compiled successfully
i  storage: uploading rules storage.rules...
i  firestore: uploading rules firestore.rules...
i  hosting[friendlychat-1234]: beginning deploy...
i  hosting[friendlychat-1234]: found 8 files in ./public
✔  hosting[friendlychat-1234]: file upload complete
✔  storage: released rules storage.rules to firebase.storage/friendlychat-1234.appspot.com
✔  firestore: released rules firestore.rules to cloud.firestore
i  hosting[friendlychat-1234]: finalizing version...
✔  hosting[friendlychat-1234]: version finalized
i  hosting[friendlychat-1234]: releasing new version...
✔  hosting[friendlychat-1234]: release complete

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview
Hosting URL: https://friendlychat-1234.firebaseapp.com
  1. قم بزيارة تطبيق الويب الخاص بك والذي تمت استضافته الآن بالكامل على شبكة CDN عالمية باستخدام استضافة Firebase في اثنين من نطاقات Firebase الفرعية الخاصة بك:
  • https://<firebase-projectId>.firebaseapp.com
  • https://<firebase-projectId>.web.app

وبدلاً من ذلك، يمكنك تشغيل firebase open hosting:site في سطر الأوامر.

تفضل بزيارة الوثائق لمعرفة المزيد حول كيفية عمل استضافة Firebase .

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

15. تهانينا!

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

ما قمت بتغطيته

  • مصادقة Firebase
  • سحابة فايرستور
  • Firebase SDK للتخزين السحابي
  • المراسلة السحابية من Firebase
  • مراقبة أداء Firebase
  • استضافة Firebase

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

يتعلم أكثر

16. [اختياري] التنفيذ من خلال التحقق من التطبيق

يساعد Firebase App Check على تأمين خدماتك من حركة المرور غير المرغوب فيها ويساعد على حماية الواجهة الخلفية لديك من سوء الاستخدام. في هذه الخطوة، ستضيف التحقق من صحة بيانات الاعتماد وتحظر العملاء غير المصرح لهم باستخدام App Check و reCAPTCHA Enterprise .

أولاً، ستحتاج إلى تمكين App Check وreCaptcha.

تمكين reCaptcha المؤسسة

  1. في وحدة التحكم السحابية، ابحث عن reCaptcha Enterprise وحدده ضمن الأمان.
  2. قم بتمكين الخدمة كما هو مطلوب، ثم انقر فوق "إنشاء مفتاح" .
  3. أدخل اسم العرض كما هو مطلوب، وحدد موقع الويب كنوع النظام الأساسي الخاص بك.
  4. أضف عناوين URL المنشورة إلى قائمة النطاق ، وتأكد من إلغاء تحديد خيار "استخدام اختبار مربع الاختيار ".
  5. انقر فوق "إنشاء مفتاح" وقم بتخزين المفتاح الذي تم إنشاؤه في مكان ما لحفظه. سوف تحتاج إليها لاحقا في هذه الخطوة.

تمكين التحقق من التطبيق

  1. في وحدة تحكم Firebase، حدد موقع قسم البناء في اللوحة اليمنى.
  2. انقر على التحقق من التطبيق ، ثم انقر على علامة التبويب طريقة تسجيل الدخول للانتقال إلى التحقق من التطبيق .
  3. انقر على "تسجيل" وأدخل مفتاح reCaptcha Enterprise عندما يُطلب منك ذلك، ثم انقر على "حفظ" .
  4. في عرض واجهات برمجة التطبيقات (APIs View)، حدد التخزين وانقر فوق فرض . افعل نفس الشيء مع Cloud Firestore .

يجب الآن فرض التحقق من التطبيق! قم بتحديث تطبيقك وحاول عرض رسائل الدردشة أو إرسالها. يجب أن تحصل على رسالة الخطأ:

Uncaught Error in snapshot listener: FirebaseError: [code=permission-denied]: Missing or insufficient permissions.

وهذا يعني أن التحقق من التطبيق يحظر الطلبات التي لم يتم التحقق منها بشكل افتراضي. الآن دعونا نضيف التحقق من الصحة إلى التطبيق الخاص بك.

انتقل إلى ملف environment.ts الخاص بك وأضف reCAPTCHAEnterpriseKey إلى كائن environment .

export const environment = {
  firebase: {
    apiKey: 'API_KEY',
    authDomain: 'PROJECT_ID.firebaseapp.com',
    databaseURL: 'https://PROJECT_ID.firebaseio.com',
    projectId: 'PROJECT_ID',
    storageBucket: 'PROJECT_ID.appspot.com',
    messagingSenderId: 'SENDER_ID',
    appId: 'APP_ID',
    measurementId: 'G-MEASUREMENT_ID',
  },
  reCAPTCHAEnterpriseKey: {
    key: "Replace with your recaptcha enterprise site key"
  },
};

استبدل قيمة key برمز reCaptcha Enterprise المميز الخاص بك.

ثم انتقل إلى ملف app.module.ts وأضف الواردات التالية:

import { getApp } from '@angular/fire/app';
import {
  ReCaptchaEnterpriseProvider,
  initializeAppCheck,
  provideAppCheck,
} from '@angular/fire/app-check';

في نفس الملف app.module.ts ، أضف إعلان المتغير العام التالي:

declare global {
  var FIREBASE_APPCHECK_DEBUG_TOKEN: boolean;
}

@NgModule({ ...

في عمليات الاستيراد، أضف تهيئة التحقق من التطبيق باستخدام ReCaptchaEnterpriseProvider ، وقم بتعيين isTokenAutoRefreshEnabled على true للسماح للرموز المميزة بالتحديث التلقائي.

imports: [
BrowserModule,
AppRoutingModule,
CommonModule,
FormsModule,
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideAppCheck(() => {
const appCheck = initializeAppCheck(getApp(), {
  provider: new ReCaptchaEnterpriseProvider(
  environment.reCAPTCHAEnterpriseKey.key
  ),
  isTokenAutoRefreshEnabled: true,
  });
  if (location.hostname === 'localhost') {
    self.FIREBASE_APPCHECK_DEBUG_TOKEN = true;
  }
  return appCheck;
}),

للسماح بالاختبار المحلي، قم بتعيين self.FIREBASE_APPCHECK_DEBUG_TOKEN على true . عندما تقوم بتحديث تطبيقك في localhost ، سيؤدي ذلك إلى تسجيل رمز تصحيح في وحدة التحكم مشابه لما يلي:

App Check debug token: CEFC0C76-7891-494B-B764-349BDFD00D00. You will need to add it to your app's App Check settings in the Firebase console for it to work.

انتقل الآن إلى عرض التطبيقات للتحقق من التطبيق في وحدة تحكم Firebase.

انقر فوق القائمة الكاملة، وحدد إدارة رموز التصحيح .

ثم، انقر فوق إضافة رمز تصحيح الأخطاء والصق رمز تصحيح الأخطاء من وحدة التحكم الخاصة بك كما هو مطلوب.

انتقل إلى ملف chat.service.ts ، وأضف الاستيراد التالي:

import { AppCheck } from '@angular/fire/app-check';

في نفس ملف chat.service.ts ، قم بإدخال App Check جنبًا إلى جنب مع خدمات Firebase الأخرى.

export class ChatService {
appCheck: AppCheck = inject(AppCheck);
...

تهانينا! يجب أن يعمل فحص التطبيق الآن في تطبيقك.