بدء استخدام "المراسلة عبر السحابة الإلكترونية من Firebase" في تطبيقات Flutter

اختيار المنصة: iOS+ Android الويب Flutter Unity C++‎


يوضّح هذا الدليل كيفية بدء استخدام Firebase Cloud Messaging في تطبيقات Flutter للعملاء لكي تتمكّن من إرسال الرسائل بشكل موثوق.

بناءً على المنصة التي تستهدفها، هناك بعض الخطوات الإضافية المطلوبة التي عليك اتّخاذها لإعداد التطبيق.

iOS+‎

تغيير وظيفة الإجراء

لاستخدام المكوّن الإضافي Flutter في FCM على أجهزة Apple، يجب تغيير وظيفة الإجراء. بدون هذا الإذن، لن تعمل ميزات Firebase الرئيسية بشكل صحيح، مثل معالجة تسجيل FCM.

Android

خدمات Google Play

تتطلّب برامج FCM أجهزة تعمل بنظام التشغيل Android 7.0 أو إصدار أحدث ومثبَّت عليها أيضًا "خدمات Google Play"، أو محاكيًا يعمل بنظام التشغيل Android 7.0 مع Google APIs. لاحظ أنك لست مقيدًا بنشر تطبيقات Android من خلال متجر Google Play.

يجب أن تتحقّق التطبيقات التي تعتمد على حزمة تطوير البرامج (SDK) لخدمات Play دائمًا من توفّر حزمة APK متوافقة لخدمات Google Play على الجهاز قبل الوصول إلى ميزات خدمات Google Play. ننصحك بإجراء ذلك في مكانَين: في إجراء onCreate() الخاص بالنشاط الرئيسي وفي إجراء onResume() الخاص به. يضمن التحقّق في "onCreate()" عدم إمكانية استخدام التطبيق بدون إجراء عملية تحقّق ناجحة. يضمن التحقّق في onResume() أنّه إذا عاد المستخدم إلى التطبيق قيد التشغيل من خلال بعض الوسائل الأخرى، مثل زر الرجوع، سيظل التحقّق جاريًا.

إذا لم يكن الجهاز يحتوي على إصدار متوافق من "خدمات Google Play"، يمكن لتطبيقك استدعاء GoogleApiAvailability.makeGooglePlayServicesAvailable() للسماح للمستخدمين بتنزيل "خدمات Google Play" من "متجر Play".

الويب

ضبط بيانات اعتماد الويب باستخدام "FCM"

تستخدم واجهة الويب في FCM بيانات اعتماد الويب التي تُعرف باسم "مفاتيح تعريف خادم التطبيقات الطوعي" (VAPID) لتفويض طلبات الإرسال إلى خدمات الإشعارات الفورية المتوافقة على الويب. للاشتراك في الإشعارات الفورية في تطبيقك، عليك ربط زوج من المفاتيح بمشروع Firebase. يمكنك إنشاء مفتاحَي تشفير جديدَين أو استيراد مفتاحَي التشفير الحاليَين من خلال وحدة تحكّم "Firebase".

تثبيت المكوّن الإضافي "FCM"

  1. ثبِّت مكوّنات Firebase الإضافية لـ Flutter وابدأها إذا لم يسبق لك إجراء ذلك.

  2. من جذر مشروع Flutter، نفِّذ الأمر التالي لتثبيت المكوّن الإضافي:

    flutter pub add firebase_messaging
    
  3. بعد الانتهاء، أعِد إنشاء تطبيق Flutter:

    flutter run
    

طلب إذن إرسال الإشعارات

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

// You may set the permission requests to "provisional" which allows the user to choose what type
// of notifications they would like to receive once the user receives a notification.
final notificationSettings = await FirebaseMessaging.instance.requestPermission(provisional: true);

// For apple platforms, make sure the APNS token is available before making any FCM plugin API calls
final apnsToken = await FirebaseMessaging.instance.getAPNSToken();
if (apnsToken != null) {
 // APNS token is available, make FCM plugin API requests...
}

الوصول إلى معرّف Firebase Installation ID

تفعيل التسجيل باستخدام معرّف تثبيت Firebase

لتفعيل تسجيل مثيل تطبيقك في FCM باستخدام رقم تعريف تثبيت Firebase، عليك أولاً تفعيل أرقام تعريف تثبيت Firebase في إعدادات تطبيقك لنظامَي التشغيل Android وApple (لا يلزم ضبط إعدادات الموافقة الثابتة على الويب):

Android

أضِف عنصر <meta-data> التالي داخل عنصر <application> في AndroidManifest.xml:

<meta-data android:name="firebase_messaging_installation_id_enabled"
           android:value="true" />

iOS+‎

أضِف مفتاح FirebaseMessagingInstallationIdEnabled إلى Info.plist واضبطه على true (YES):

<key>FirebaseMessagingInstallationIdEnabled</key>
<true/>

الاشتراك في بث "onRegistered"

لإرسال رسالة إلى نسخة افتراضية من تطبيقك على جهاز معيّن، تحتاج إلى رقم تعريف تثبيت Firebase (FID) لتلك النسخة الافتراضية من التطبيق بعد تسجيلها في FCM. يتم إرسال FID بشكل غير متزامن من خلال مصدر بيانات onRegistered.

على نظامَي Android وApple، تسجّل FCM تلقائيًا مثيل التطبيق عند بدء التشغيل عندما تكون ميزة الإعداد التلقائي مفعَّلة (الإعداد التلقائي). ومع ذلك، يجب إجراء استدعاء صريح لـ register():

  • على الويب يمكنك اختياريًا تمرير vapidKey وserviceWorkerScriptPath.
  • على نظامَي التشغيل Android وApple في حال إيقاف الإعداد التلقائي أو بعد استدعاء unregister() يمكنك أيضًا استدعاء register() في أي وقت لتشغيل onRegistered باستخدام معرّف FID المسجَّل مسبقًا.

يجب دائمًا الاشتراك في onRegistered قبل طلب register() لكي يكون المستمع نشطًا عند إرسال حدث التسجيل:

final messaging = FirebaseMessaging.instance;

messaging.onRegistered
    .listen((String installationId) {
      // TODO: Send the Firebase Installation ID (FID) to your application server.
    })
    .onError((err) {
      // Error getting Firebase Installation ID.
    });

// Required on Web, and on Android/Apple if auto-initialization is disabled.
await messaging.register(
  // Optional on Web (ignored on Android and Apple platforms)
  vapidKey: "BKagOny0KF_2pCJQ3m....moL0ewzQ8rZu",
);

يُصدر مسار بيانات onRegistered مقياس FID في الحالات التالية:

  1. يتم ذلك تلقائيًا عند بدء تشغيل التطبيق لأول مرة والمزامنة الروتينية على نظامَي التشغيل Android وApple عند تفعيل الإعداد التلقائي.
  2. في كل مرة ينتهي فيها طلب register() يدوي (حتى إذا كان مثيل التطبيق مسجَّلاً من قبل، لا يزال onRegistered يصدر معرّف مثيل Firebase المسجَّل من قبل).
  3. عندما يتم رصد تغيير في معرّف تثبيت Firebase وإعادة تسجيل التطبيق في FCM، أو على الويب عند بدء حدث pushsubscriptionchange.

بعد الحصول على معرّف Firebase Installation ID‏ (FID)، أرسِله إلى خادم تطبيقك وخزِّنه باستخدام الطريقة المفضّلة لديك.

الوصول إلى رمز التسجيل المميّز (متوقّف نهائيًا)

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

على منصات الويب، مرِّر مفتاح VAPID العام إلى getToken():

final fcmToken = await FirebaseMessaging.instance.getToken(vapidKey: "BKagOny0KF_2pCJQ3m....moL0ewzQ8rZu");

لتلقّي إشعار عند تعديل الرمز المميّز، اشترِك في البث onTokenRefresh:

FirebaseMessaging.instance.onTokenRefresh
    .listen((fcmToken) {
      // TODO: If necessary send token to application server.

      // Note: This callback is fired at each app startup and whenever a new
      // token is generated.
    })
    .onError((err) {
      // Error getting token.
    });

منع الإعداد التلقائي

عند إنشاء تسجيل FCM، تُحمّل المكتبة المعرّف وبيانات الإعداد إلى Firebase. إذا كنت تفضّل منع التسجيل التلقائي، يمكنك إيقاف الإعداد التلقائي في وقت الإنشاء.

عند إيقاف الإعداد التلقائي، يمكنك تسجيل مثيل التطبيق بشكل صريح في وقت التشغيل من خلال استدعاء register() (تأكَّد من الاشتراك في onRegistered أولاً لتلقّي معرّف تثبيت Firebase):

await FirebaseMessaging.instance.register();

iOS

على أجهزة iOS، أضِف قيمة بيانات وصفية إلى Info.plist:

FirebaseMessagingAutoInitEnabled = NO

Android

على Android، أوقِف جمع بيانات "إحصاءات Google" وبدء التشغيل التلقائي لخدمة FCM (يجب إيقاف كليهما) من خلال إضافة قيم البيانات الوصفية هذه إلى AndroidManifest.xml:

<meta-data
    android:name="firebase_messaging_auto_init_enabled"
    android:value="false" />
<meta-data
    android:name="firebase_analytics_collection_enabled"
    android:value="false" />

إعادة تفعيل الإعداد التلقائي لـ "FCM" في وقت التشغيل

لتفعيل الإعداد التلقائي لمثيل تطبيق معيّن، يمكنك استدعاء setAutoInitEnabled():

await FirebaseMessaging.instance.setAutoInitEnabled(true);

وتظل هذه القيمة محفوظة عند إعادة تشغيل التطبيق بعد ضبطها.

إرسال رسالة إشعار تجريبية

  1. ثبِّت التطبيق وشغِّله على جهاز الاختبار. على أجهزة Apple، عليك قبول طلب الإذن لتلقّي الإشعارات عن بُعد.

  2. تأكَّد من أنّ التطبيق يعمل في الخلفية على الجهاز.

  3. في وحدة تحكّم Firebase، انتقِل إلى DevOps & Engagement > المراسلة.

  4. أنشئ حملة.

    • إذا كانت هذه رسالتك الأولى:

      1. انقر على إنشاء حملتك الأولى.

      2. اختَر رسائل إشعارات Firebase، ثمّ انقر على إنشاء.

    • إذا سبق لك إنشاء حملات:

      1. في علامة التبويب الحملات، انقر على حملة جديدة.

      2. انقر على الإشعارات.

  5. أدخِل نص الرسالة.

  6. انقر على إرسال رسالة اختبار من اللوحة اليسرى.

  7. في الحقل الذي يحمل التصنيف إضافة معرّف تثبيت Firebase أو FCM رمز مميّز للتسجيل، أدخِل معرّف تثبيت Firebase المسجّل أو الرمز المميّز للتسجيل.

  8. اختَر اختبار.

بعد اختيار اختبار، من المفترض أن يتلقّى جهاز العميل المستهدَف الإشعار، مع تشغيل التطبيق في الخلفية.

للحصول على إحصاءات حول تسليم الرسائل إلى تطبيقك، انتقِل إلى لوحة بيانات DevOps & Engagement > Messaging > Reports في وحدة تحكّم Firebase. تسجّل لوحة البيانات هذه عدد الرسائل المُرسَلة والمفتوحة على أجهزة Apple وAndroid، بالإضافة إلى بيانات "مرّات الظهور" (الإشعارات التي يراها المستخدمون) لتطبيقات Android.

التعامل مع التفاعل

عندما ينقر المستخدمون على إشعار، يكون الإعداد التلقائي على كل من Android وiOS هو فتح التطبيق. إذا تم إنهاء التطبيق، سيتم تشغيله، وإذا كان في الخلفية، سيتم نقله إلى المقدّمة.

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

توفّر حزمة firebase-messaging طريقتَين للتعامل مع هذا التفاعل:

  1. getInitialMessage(): إذا تم فتح التطبيق من حالة إنهاء، ستعرض هذه الطريقة Future يحتوي على RemoteMessage. بعد استهلاكها، ستتم إزالة "RemoteMessage".
  2. onMessageOpenedApp: يمثّل هذا المَعلمة Stream التي تنشر RemoteMessage عند فتح التطبيق من حالة الخلفية.

لضمان حصول المستخدمين على تجربة سلسة، يجب التعامل مع كلا السيناريوهَين. يوضّح مثال الرمز البرمجي التالي كيفية تحقيق ذلك:

class Application extends StatefulWidget {
  @override
  State createState() => _Application();
}

class _Application extends State {
  // In this example, suppose that all messages contain a data field with the key 'type'.
  Future setupInteractedMessage() async {
    // Get any messages which caused the application to open from
    // a terminated state.
    RemoteMessage? initialMessage =
        await FirebaseMessaging.instance.getInitialMessage();

    // If the message also contains a data property with a "type" of "chat",
    // navigate to a chat screen
    if (initialMessage != null) {
      _handleMessage(initialMessage);
    }

    // Also handle any interaction when the app is in the background using a
    // Stream listener
    FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
  }

  void _handleMessage(RemoteMessage message) {
    if (message.data['type'] == 'chat') {
      Navigator.pushNamed(context, '/chat',
        arguments: ChatArguments(message),
      );
    }
  }

  @override
  void initState() {
    super.initState();

    // Run code required to handle interacted messages in an async function
    // as initState() must not be async
    setupInteractedMessage();
  }

  @override
  Widget build(BuildContext context) {
    return Text("...");
  }
}

تعتمد طريقة التعامل مع التفاعل على الإعدادات التي تضبطها. المثال المعروض سابقًا هو مثال أساسي على استخدام StatefulWidget.

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

بعد إكمال خطوات الإعداد، إليك بعض الخيارات للمضي قدمًا في استخدام "FCM" في Flutter: