Call onMessage method when the app is in background in flutter

14,803

Solution 1

I see you are forcibly showing a notification when the onMessage is triggered, you don't need to do that if the app is in background, the notifications will be automatically created.

The onMessage is triggered when you receive a notification and the app is open, running in foreground. For instance, you have the Gmail app open, and a new e-mail is received, in this case you don't need a notification poping in the notification area. The app might choose to handle it directly, and the onMessage is triggered as soon as the notification is received - which is good so you don't need to keep pooling the server.

The onResume and onLaunch are a bit different - these two events are not triggered when the notification is received. They are only triggered when the user selects/taps the notification from the notification area. So, in both cases, the app is currently hidden, either by not running at all (terminated), or the app is in background - not being shown. In this case, the notification is received in the phone and automatically placed in the notification area (you don't need to code a "showNotification" for that). At this state, the user can see the notification but the app itself it not yet aware of it.

The app will only become aware of the notification when the user selects one of these notifications.

If the app is not running at all, the onLaunch will be triggered when the user taps the notification. It means the app was not running and as a result of the notification it had to 'launch from scratch'.

If the app is in background, the onResume will be triggered when the user selects the notification, resuming the app to the foreground state.

EDIT:

As pointed out by @boformer this only applies for 'Notification' messages. If you're sending 'Data' messages, no notification is created and the messages are delivered only through onMessage. More details in the plugin readme and firebase docs.

Solution 2

According with the last plugin Firebase Cloud Messaging for Flutter version 4.0.0+1, when you create or compile your push notification on console or form make sure to include

click_action: FLUTTER_NOTIFICATION_CLICK 

as a "Custom data" key-value-pair (under "Advanced options") when targeting an Android device. This option enabling the onResume when your app is in background state.

Solution 3

The Dart VM does not run while the app is in background. That means you have to handle notifications and data messages in native code (Java/Kotlin/ObjectiveC/Swift).

To do this on Android, refer to the official documentation.

You will probably have to remove the firebase_messaging plugin and do all the message handling manually. To send the notification content to your flutter app (while it is in foreground), use platform channels.

It really helps to look at the source code of the firebase_messaging plugin to see what happens on the native side.

Share:
14,803
Admin
Author by

Admin

Updated on December 06, 2022

Comments

  • Admin
    Admin over 1 year

    I'm new in flutter and dart. I'm trying to connect my app with FCM. When app is in foreground I create flutterLocalNotificationsPlugin and everything works fine, but I don't how to handle onMessage method when my app is in background. Have somebody any idea how I can resolve it?

    FirebaseMessaging firebaseMessaging = new FirebaseMessaging();
    FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();
    
    @override
    void initState() {
     super.initState();
    
     var androidInitSettings = new AndroidInitializationSettings('mipmap/ic_launcher');
     var iosInitSettings = new IOSInitializationSettings();
     var initSettings = new InitializationSettings(androidInitSettings, iosInitSettings);
     flutterLocalNotificationsPlugin.initialize(initSettings, selectNotification: onSelectNotification);
    
     firebaseMessaging.configure(
       onLaunch: (Map<String, dynamic> msg) {
         print(" onLaunch called ${(msg)}");
       },
       onResume: (Map<String, dynamic> msg) {
         print(" onResume called ${(msg)}");
       },
       onMessage: (Map<String, dynamic> msg) {
         showNotification(msg);
         print(" onMessage called ${(msg)}");
       },
     );
     firebaseMessaging.requestNotificationPermissions(const IosNotificationSettings(sound: true, alert: true, badge: true));
     firebaseMessaging.onIosSettingsRegistered.listen((IosNotificationSettings setting) {
       print('IOS Setting Registed');
     });
     firebaseMessaging.getToken().then((token) {
       update(token);
     });
    }