التنبيهات بإستخدام FCM في تطبيقات Flutter في Foreground.

في هذه التدوينة سنقوم بعرض التنبيهات للمستخدم داخل التطبيق وايضًا عند الضغط على التنبيه يقوم بتوجيهه الى شاشة محددة. في الدرس السابق تعلمنا كيف نقوم بتهيئة FCM في Android و IOS وهذا سيكون المكمل له.


استقبال التنبيهات في Foreground.

اذا قمت بإرسال تنبيه للمستخدم وهو داخل التطبيق، فرن التنبيه لن يظهر للمستخدم مالم تقم بإضافة رسالة تنبيه او تنبيه داخلي. ويمكن القيام بذلك بإستخدام حُزمة Local Notification في تطبيقات Flutter.

flutter pub add flutter_local_notifications

او من ملف pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  flutter_local_notifications: ^12.0.1+1
  • تهيئة Local Notification للأندرويد.

نحتاج الى إضافة بعض الاكواد لجعل Local Notification متوافق مع الأندرويد و Firebase.

أندرويد يقوم بالتعامل مع التنبيهات القادمة على عاملين مختلفة:

١ – اذا كان التطبيق مغلق او في الخلفية فستكون القناة المُسندة “Channel” تقرر كيف سيكون ظهور التنبية.

٢ – اذا كان التطبيق مفتوح او شاشة التطبيق ظاهرة للمستخدم ـForeground فالتنبية لن يظهر.

اذا كنت تستخدم أندرويد ودخلت على أحد التطبيقات ستلاحظ هناك خيار خاص بالتنبيهات عند الدخول اليه ستجد عدة خيارات تستطيع تحديد التنبيه الذي تريده ان يصل لك. هذا هو Notification Channel

Notification Channel

لجعل التطبيق يطهر للمستخدم خلال استخدامة للتطبيق سنقوم بإنشاء Channel جديد لأن القناة الإفتراضية لـFCM تكون اهميتها default. في حال اردنا اظهار التنبيه للمستخدم سنقوم بإنشاء قناة تكون الأهمية فيها عالية max . قم بإضافة الكود التالي في أعلى الصفحة في main.dart

const AndroidNotificationChannel channel = AndroidNotificationChannel(
  'high_importance_channel', // id
  'High Importance Notifications', // title
  'This channel is used for important notifications.', // description
  importance: Importance.max,
);
  • انشاء Channel في الجهاز، اذا كانت نفس الرقم موجود سابقًا سيقوم بتحديثها.
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
    FlutterLocalNotificationsPlugin();

await flutterLocalNotificationsPlugin
  .resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
  ?.createNotificationChannel(channel);

الآن بعد إنشاء القناة سنقوم بجعل FCM يستخدمها بدل القناة الإفتراضية. وذلك عن طريق تعديل ملف AndroidManifest.xml

<meta-data
  android:name="com.google.firebase.messaging.default_notification_channel_id"
  android:value="high_importance_channel" />
اسم Channel الخاصة بالتنبية داخل التطبيق
  • اظهار التنبية داخل التطبيق.

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

 FirebaseMessaging.onMessage.listen((RemoteMessage event) {
      RemoteNotification notification = event.notification!;
      AndroidNotification? android = event.notification?.android;
      NotificationService().showNotification(
        notification: notification,
        android: android,
      );
      // If `onMessage` is triggered with a notification, construct our own
      // local notification to show to users using the created channel.
      if (android != null) {}
    });
  • شغل التطبيق وارسل تنبية.

عند تشغيل التطبيق وإرسال تنبية ستظهر الرسالة للمستخدم داخل التطبيق. ستكون النتيجة كالفيديو في الأسفل.

التنبية داخل التطبيق.
  • تهيئة IOS.

مقارنة بالتهيئة في الأندرويد في الايفون العملية تكون مباشرة بدون اي خطوات اضافية، عن طريق setForegroundNotificationPresentationOptions سيتمكن مستخدمي أيفون من استقبال التنبيهات مباشرة اثناء استخدامهم للتطبيق.

await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
  alert: true, // Required to display a heads up notification
  badge: true,
  sound: true,
);

الخاتمة

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

class NotificationService {
  //Singleton pattern
  static final NotificationService _notificationService =
      NotificationService._internal();
  factory NotificationService() {
    return _notificationService;
  }
  NotificationService._internal();

  //instance of FlutterLocalNotificationsPlugin
  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();

  Future<void> init() async {
    //Initialization Settings for Android
    final AndroidInitializationSettings initializationSettingsAndroid =
        const AndroidInitializationSettings('ic_stat_notifications_none');

    //InitializationSettings for initializing settings for both platforms (Android & iOS)
    final InitializationSettings initializationSettings =
        InitializationSettings(
      android: initializationSettingsAndroid,
    );

    await flutterLocalNotificationsPlugin.initialize(
      initializationSettings,
    );
  }

  Future<void> showNotification(
      {required RemoteNotification notification,
      AndroidNotification? android}) async {
    flutterLocalNotificationsPlugin.show(
        notification.hashCode,
        notification.title,
        notification.body,
        NotificationDetails(
          android: AndroidNotificationDetails(
            channel.id,
            channel.name,
            priority: Priority.high,
            importance: Importance.high,
            icon: android?.smallIcon,
          ),
        ));
  }
}
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  await NotificationService().init(); //
  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();

  await flutterLocalNotificationsPlugin
      .resolvePlatformSpecificImplementation<
          AndroidFlutterLocalNotificationsPlugin>()
      ?.createNotificationChannel(channel);
  runApp(const MyApp());
}

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *