FCM notifications delivering only with the app opened (iOS Flutter)

963

It seams that you are sending a data message rather than a notification message. The behavior that you described (notification is sent when you reopen the app) is the behavior of a data message. More info on that in the docs.

Share:
963
Admin
Author by

Admin

Updated on December 27, 2022

Comments

  • Admin
    Admin over 1 year

    In this project, if one given user do something, the others receive a push from Firebase Messaging. In android it is working fine, but in iOS the message arrives on the users phones only if the app is opened. If in background, when you app again the app, it shows the notification

    Things I already did:

    • 1 Create a key in developers.apple and apply it within firebase
    • 2 feed my project with googleservices.plist
    • 3 turn on Push Notifications and Background Modes, and enable Background fetch and Remote notifications under Background Modes.
    • 4 Added this code in my info.plist:
    <key>FirebaseScreenReportingEnabled</key>
    <true/>
    <key>FirebaseAppDelegateProxyEnabled</key>
    <true/>
    

    And in AppDelegate.swift, I already tried this two codes: 1 (from FirebaseMessaging documentation)

    import UIKit
    import Flutter
    
    @UIApplicationMain
    @objc class AppDelegate: FlutterAppDelegate {
      override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
      ) -> Bool {
        if #available(iOS 10.0, *) {
          UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
        }
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
      }
    }
    
    

    and 2

    import UIKit
    import Flutter
    import Firebase
    
    @UIApplicationMain
    @objc class AppDelegate: FlutterAppDelegate {
      override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
      ) -> Bool {
        if #available(iOS 10.0, *) {
          // For iOS 10 display notification (sent via APNS)
          UNUserNotificationCenter.current().delegate = self
    
          let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
          UNUserNotificationCenter.current().requestAuthorization(
            options: authOptions,
            completionHandler: {_, _ in })
        } else {
          let settings: UIUserNotificationSettings =
          UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
          application.registerUserNotificationSettings(settings)
        }
    
        application.registerForRemoteNotifications()
        FirebaseApp.configure()
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
      }
    }
    
    
    

    The second one arrives the messages with the app opened, with the first one it don't arrive at all. I'm using FlutterLocalNotifications to treat when the app is opened, and might be some conflicts between LocalNotifications and FCM (I'm not sure, just thinking).

    How could I handle that to receive background notifications too?:

    There are something I miss? The following code is my PushNotifications.dart

    import 'dart:async';
    import 'dart:convert';
    import 'dart:io';
    
    import 'package:app_md/providers/auth_provider.dart';
    import 'package:app_md/providers/notification_plugin.dart';
    import 'package:app_md/utils/app_routes.dart';
    import 'package:firebase_messaging/firebase_messaging.dart';
    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    import 'package:http/http.dart' as http;
    
    Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
      if (message.containsKey('data')) {
        // Handle data message
        final dynamic data = message['data'];
      }
    
      if (message.containsKey('notification')) {
        // Handle notification message
        final dynamic notification = message['notification'];
      }
    
      // Or do other work.
    }
    
    class PushNotificationsManager {
    
      PushNotificationsManager._();
    
      factory PushNotificationsManager() => _instance;
    
      static final PushNotificationsManager _instance = PushNotificationsManager
          ._();
    
      final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
      final NotificationPlugin _notificationPlugin = NotificationPlugin();
    
    
    
      Future<void> init() async {
        if (Platform.isIOS) {
          _firebaseMessaging.requestNotificationPermissions(
              IosNotificationSettings());
        }
        _firebaseMessaging.configure(
          // Called when the app is in the foreground and we receive a push notif.
          onMessage: (Map<String, dynamic> message) async {
            print("onMessage: ${message}");
            print(message['notification']['body']);
            _notificationPlugin.showNotification(
                title: 's',
                content: message['notification']['body']
            );
            //sendNotification();
          },
          // Called when the app has been closed completely and its opened
          // from the notification directly
          onBackgroundMessage: Platform.isAndroid ? myBackgroundMessageHandler:null,
          onLaunch: (Map<String, dynamic> message) async {
            print("onLaunch: $message");
    
           // _navigateToItemDetail(message);
          },
          // Called when the app is in the background and its opened from the notif
          onResume: (Map<String, dynamic> message) async {
            print("onMessage: ${message}");
          },
        );
    
      }
    
      subscribeToTopicNotification() async {
        await _firebaseMessaging.subscribeToTopic("MYTOPIC");
      }
    
      unsubscribeToTopicNotification() async {
        await _firebaseMessaging.unsubscribeFromTopic("MYTOPIC");
      }
    
      Future sendNotification(String body, String title, bool isAdm) async {
        !isAdm ? subscribeToTopicNotification() : null;
        final String url = 'https://fcm.googleapis.com/fcm/send';
        var data;
        data =
        '{"notification": {"body": "${body}", "title": "${title}", "content_available": "true"}, "priority": "high", "data": {"click_action": "FLUTTER_NOTIFICATION_CLICK"}, "to": "/topics/MYTOPIC"}';
        final response = await http.post(
            url,
            headers: <String, String>{
              "Content-Type": "application/json",
              "Keep-Alive": "timeout=5",
              "Authorization": "MYKEY"
            },
            body: data
        );
    
        print(response.body);
      }
    }
    
    
  • Admin
    Admin over 3 years
    I drop out the 'data' from my http request and still face the problem. It is strange because in Android all works fine, and iOS don't
  • Mohammad Kurjieh
    Mohammad Kurjieh over 3 years
    In Android, the onMessage() is triggered even if the app is in the background however on IOS it will not fire. So please recheck it, since if it was a data message this behavior is expected. What version of firebase are you using?
  • Admin
    Admin over 3 years
    firebase_storage: ^5.1.0 firebase_core: ^0.5.3 cloud_firestore: ^0.14.4 firebase_messaging: ^7.0.3 firebase_analytics: ^6.3.0
  • Mohammad Kurjieh
    Mohammad Kurjieh over 3 years
    Hmmm this weird, try to use the 8.0 dev version, if it was an issue with firebase it will most definitely be fixed by now since this is a very serious issue. But I still think the issue is the one that I described above.
  • Admin
    Admin over 3 years
    What you said makes sense, but look to my post body: '{"notification": {"body": "${body}", "title": "${title}", "content_available": "true"}, "priority": "high", "to": "/TOPIC"}'; There is no reference to data here, why is it attributing this to a data message?
  • Mohammad Kurjieh
    Mohammad Kurjieh over 3 years
    Yes I see what you are talking about, can you try to send a combined message Link
  • Mohammad Kurjieh
    Mohammad Kurjieh over 3 years
    Another thing did you do all the steps mentioned here
  • Admin
    Admin over 3 years