user3833732
user3833732

Reputation: 901

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

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.

Upvotes: 1

Views: 5246

Answers (2)

user3833732
user3833732

Reputation: 901

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

Upvotes: 2

Junsu Cho
Junsu Cho

Reputation: 854

ios is impossible android is possible, remove notification payload

{
"to": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
"notification":
    {
        "title": "title"
    }
"data":
    {
      "data" : "data"
    }
}

to

{
"to": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
"data":
    {
      "data" : "data"
    }
}

Upvotes: 0

Related Questions