简体   繁体   中英

How to show a Local Notification in Flutter, when the app is in Background/Terminated and it receives an FCM notification?

I am trying Implemented push notification service using Firebase Cloud Messaging in my Flutter app. This is how FCM documentation says we should handle notifications, according to the current state (foreground, background or terminated) of our app:

Foreground : we have an onMessage stream, that we can listen to, but FCM will not show any notification when in foreground state, so we have to use FlutterLocalNotificationsPlugin for that, this is my implementation of it:

FirebaseMessaging.onMessage.listen((RemoteMessage remoteMessage) {
      // calling flutter local notifications plugin for showing local notification
      scheduleNotification(remoteMessage);
    });

in scheduleNotification method I call the FlutterLocalNotificationsPlugin().show() method, and everything works as expected till now .

The problem starts here:

Background, Terminated : Firebase automatically shows a notification in this state and it has a onBackgroundMessage. method, to which we can pass an BackgroundMessageHandler which runs after FCM has shown the notification. This is my implementation of the background handler:

Future<void> backgroundMessageHandler(
    RemoteMessage remoteMessage) async {
  RemoteNotification? remoteNotification = remoteMessage.notification;
  if (remoteNotification != null) {
    FlutterLocalNotificationsPlugin().show(
        remoteMessage.messageId.hashCode,
        remoteNotification.title,
        remoteNotification.body,
        NotificationDetails(
          android: AndroidNotificationDetails(
              _androidNotificationChannel.id,
              _androidNotificationChannel.name,
              _androidNotificationChannel.description,
              icon: 'launch_background',
              importance: Importance.max),
        ));
  }
}

Problem : Every time my app receives a notification from FCM, my app shows TWO notifications, one is shown automatically by FCM, and the second one is shown by the FlutterLocalNotificationsPlugin().show() method that i am calling in the BackgroundMessageHandler .

Tl:dr

How do I prevent FCM to show any notifications automatically and only show it via FlutterLocalNotificationsPlugin().show() method?

One solution is, I don't send notifications from FCM and only send Data Messages, for which FCM doesn't show any notification. but, i don't think its the right way.

I am answering my own question here, After some research, I found out in the FCM docs that it does mention to use data only messages if we want to handle displaying the notifications on client side. We can read about it here

Client app is responsible for processing data messages. Data messages have only custom key-value pairs with no reserved key names (see below).

Use notification messages when you want FCM to handle displaying a notification on your client app's behalf. Use data messages when you want to process the messages on your client app.

This thing is also mentioned in the flutter fire docs ,

Your application code can then handle messages as you see fit; updating local cache, displaying a notification or updating UI. The possibilities are endless!

So that is the answer I guess, I just don't have to use the "notification" field when delivering an FCM message, and FCM Plugin on the client will not show notification automatically. I still think this should be made more clear in the docs, caused a lot of confusion and research and I still think its a bit odd, when our intention is to show notification to the user, but we are still omitting the "notification" field.

Remove the FlutterLocalNotificationsPlugin().show call from the code above. You do not need to manually show the notification.

As you said, the notification is already shown when this code is run.

Or am I missing something?

I had the same problem at the beginning as a solution I omitted the notification sending in the json but after trying and testing, I discovered that I could send notification and data without having the double push notification problem, it was solved.

solution: check your onbackgroundhandler and validate the data if (message.data.message ['android_channel_id'] == my channel) {

flutterLocalNotificationsPlugin.show (

);

}

fcm server heredado

message: { to: $token notification: $notification data: { title: $title body: $body id: "id", }; }

Future<void> backgroundMessageHandler(
RemoteMessage remoteMessage) async {

if (remoteMessage.data['id'].= null) { FlutterLocalNotificationsPlugin(),show( 0. remoteMessage,data['title']. remoteMessage,data['body']: NotificationDetails( android. AndroidNotificationDetails( _androidNotificationChannel,id. _androidNotificationChannel,name. _androidNotificationChannel,description: icon, 'launch_background': importance. Importance,max); )); } }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM