Flutter Firebase Cloud Messaging how to Auto Dismiss/Cancel a notification?

1,670

These are the steps to accomplish the following

  • receiving a notification without disturbing the user(silently without any Alert in the system tray)
  • let localNotification Pkg start the progress Notification
  • do a background task and when finished
  • cancel the notification via LocalNotifications Pkg

enter image description here

Make sure you have the following in your .yaml file... at the time of solving this I had the following versions:

  firebase_messaging: ^11.1.0
  firebase_core: ^1.10.0
  flutter_local_notifications: ^9.1.

For the Local Notification Package lets make a class to use its services

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';

class LocalNotificationService {
  static final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin();

  static void initialize(BuildContext context) {
    final InitializationSettings initializationSettings = InitializationSettings(
        android: const AndroidInitializationSettings("@mipmap/your_icon"));

    _notificationsPlugin.initialize(initializationSettings);
  }


//=================================================
//==============this is the update notification

  static Future<void> showProgressNotification() async {
    const int maxProgress = 5;
    for (int i = 0; i <= maxProgress; i++) {
      await Future<void>.delayed(const Duration(seconds: 1), () async {
        final AndroidNotificationDetails androidPlatformChannelSpecifics =
        AndroidNotificationDetails('progress channel', 'progress channel',
            channelDescription: 'progress channel description',
            channelShowBadge: false,
            importance: Importance.max,
            priority: Priority.high,
            playSound: false,
            showProgress: true,
            maxProgress: maxProgress,
            progress: i);
        final NotificationDetails platformChannelSpecifics =
        NotificationDetails(android: androidPlatformChannelSpecifics);
        await _notificationsPlugin.show(
            0,//I use this id to cancel it from below method
            'progress notification title',
            'progress notification body',
            platformChannelSpecifics,
            payload: 'item x');
      });
    }
  }

  //=========================and this is for the ProgressNotification to be cancelled
  static Future<void> cancelNotification() async {
    await _notificationsPlugin.cancel(0);
  }

}//end of class

Make your you initialize it in the init method of your Widget

@override
  void initState()  {
    // TODO: implement initState
    super.initState();

    LocalNotificationService.initialize(context);
}

And lastly... this is how your Main() and top handler will look

//Receive message when app is in background/minimized 
//THIS IS THE TOP LEVEL HANDLER.. as it is outside the scope of main()
Future<void> backgroundHandler(RemoteMessage message) async{
  print("from the Background Handler Top Function()..............");
  print(message.data.toString()); 
  //now for the localNotification to take over
  await LocalNotificationService.showProgressNotification();
  await Future<void>.delayed(const Duration(seconds: 2));//faking task delay
  await LocalNotificationService.cancelNotification();//by default I have made id=0
}



void main() async{
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  FirebaseMessaging.onBackgroundMessage(backgroundHandler);//this has to be a TOP LEVEL METHOD
  runApp(MyApp());
}

And on the Server side while sending the notification make sure there is only data{}... see @Junsu Cho answer

Share:
1,670
user3833732
Author by

user3833732

Updated on January 02, 2023

Comments

  • user3833732
    user3833732 over 1 year

    I have successfully managed to receive FCM messages(on my mobile) via the console as well as from my NodeJs server. But how may I send & receive an FCM message that will arrive at my phone, do some tasks and then auto Cancel/Dismiss by itself?

    Is this possible in Flutter with FCM? In Android we use to have public Notification.Builder setTimeoutAfter (long durationMs)

    Its more for just pinging the client app... and retrieving some data from the Apps local storage. Since it can be done automatically i want to do it without troubling the user.

    • Junsu Cho
      Junsu Cho over 2 years
      Why not use Job Scheduler? To ping (whether the smartphone app is alive) or to read local data, you can use Job Scheduler ios: backgroudbatch.
    • Yo Apps
      Yo Apps over 2 years
      It seems like the user is using an external system like a cronjob server.
    • user3833732
      user3833732 over 2 years
      Yes thats true. We want to use an external service like a CronJob. We dont want any background checking like JobScheduler or Background Fetch.
  • user3833732
    user3833732 over 2 years
    Yes, we did try this... this wont make the Notification appear in the SystemTray... But we want that the notification appears, lets the task finish... and then cancels itself. Thats the real problem... any ideas?
  • Junsu Cho
    Junsu Cho over 2 years
    Since fcm is a one-way protocol, it is not possible to automatically dismiss. my idea is run the service with a push using fcm, end the task using the service, and then terminate the service.
  • user3833732
    user3833732 over 2 years
    Yes, back here we're beginning to think that too. So lets give it a few days or else we will go with your recommendation.
  • Luca Jeevanjee
    Luca Jeevanjee almost 2 years
    Also impossible on android if you want to set a channel id