How to get flutter local notification on iOS using only FCM data message?

502

I found a solution.

I changed this:

notification: {
   title: "title",
   body: "new post",
},

to:

notification: {
   sound: "default",
},

In this way I wont get automatic push notification and I can handle data message on iOS.

Share:
502
Dodo
Author by

Dodo

Updated on January 04, 2023

Comments

  • Dodo
    Dodo about 1 year

    I have an app that send notifications if someone commented or published a new post. I use FCM and flutter local notification. It works well on Android, but on iOS it does not. I realized if I add a 'notification' message block to the firebase function then finally I get the data message BUT I get the notification message too at the same time. That is not what I want. If I remove Notification message then data message not triggered and I do not get any notification. The app should works only from iOS 10+. I tried this on iOS 15. This is my firebase function:

    exports.myFunction = functions.firestore
        .document("animal/{message}")
        .onCreate((snapshot, context) => {
          return admin.messaging().sendToTopic("animal", {
            data: {
              latitude: snapshot.data()["latitude"].toString(),
              longitude: snapshot.data()["longitude"].toString(),
              title: snapshot.data().username,
              body: snapshot.data().description,
              uid: snapshot.data().userId,
              animalId: snapshot.id,
            },
            //I do not want to use this, but if I remove this I do not get any push notification. Data notification neither.
           //On Android it does not matter if I delete notification block or no. I will get the data notification. 
            notification: {
              title: "title",
              body: "new post",
            },
          });
        });
    

    In main.dart there is the flutter local notification initializing

    Future<void> main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await Firebase.initializeApp(
        options: DefaultFirebaseOptions.currentPlatform,
      );
    
      final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
          FlutterLocalNotificationsPlugin();
      final AndroidInitializationSettings _initialzationSettingsAndriod =
          AndroidInitializationSettings('noticon');
      final IOSInitializationSettings _initialzationSettingsIOS =
          IOSInitializationSettings(
        requestAlertPermission: false,
        requestBadgePermission: false,
        requestSoundPermission: false,
      );
      final InitializationSettings _initializationSettings = InitializationSettings(
          android: _initialzationSettingsAndriod, iOS: _initialzationSettingsIOS);
      _flutterLocalNotificationsPlugin
          .resolvePlatformSpecificImplementation<
              AndroidFlutterLocalNotificationsPlugin>()
          ?.createNotificationChannel(channel);
      await _flutterLocalNotificationsPlugin.initialize(
        _initializationSettings,
        onSelectNotification: (payload) async {
          if (payload != null) {
            debugPrint('notification payload: ' + payload);
          }
          initPayload = payload!;
          await navigatorKey.currentState!.push(CupertinoPageRoute<void>(
            builder: (BuildContext context) => AnimalDetailScreen(payload, true),
          ));
        },
      );
    
    ....
    
    @override
      void initState() {
        super.initState();
        _requestPermissions();
        final messaging = FirebaseMessaging.instance;
        messaging.subscribeToTopic('animal');
        messaging.subscribeToTopic('notifications');
        messaging.requestPermission(
          alert: true,
          sound: true,
          badge: true,
          provisional: false,
        );
    

    And this is the showing notification. If I remove the notification message from firebase function then onMessage cannot be called on iOS but on only Android.

    
    
        FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
          print("onMessage called");
          ....
          if (isValid && currentUser != message.data['uid']) {
             showNotification(message);
             notifierCounter.value = notifierCounter.value + 1;
          }
        }
    
    ...
    showNotification(RemoteMessage message) async {
      Map<String, dynamic> data = message.data;
      await flutterLocalNotificationsPlugin.show(
          data.hashCode,
          data['title'],
          data['body'],
          NotificationDetails(
            android: AndroidNotificationDetails(
              channel.id,
              channel.name,
              channelDescription: channel.description,
              priority: Priority.high,
            ),
            iOS: IOSNotificationDetails(),
          ),
          payload: data['animalId'],
        );
      }