Flutter: Push notifications even if the app is closed

84,840

Solution 1

For reminders i would recomend Flutter Local Notifications Plugin. It has a powerful scheduling api. From the documentation of local notification:

Scheduling when notifications should appear - Periodically show a notification (interval-based) - Schedule a notification to be shown daily at a specified time - Schedule a notification to be shown weekly on a specified day and time - Ability to handle when a user has tapped on a notification when the app is the foreground, background or terminated

And for push notification, you can use Firebase Cloud Messaging or one signal plugin or you can implement natively through platform-channels

Edit: You can also fire notifications according to specific conditions even if the app is terminated. This can be achevied by running dart code in the background. Quoting from the official faq:

Can I run Dart code in the background of an Flutter app? Yes, you can run Dart code in a background process on both iOS and Android. For more information, see the Medium article Executing Dart in the Background with Flutter Plugins and Geofencing.

Solution 2

I have found a solution to this problem. We just have to register the Local Notification Plugin in the Application class.

First Create a class FlutterLocalNotificationPluginRegistrant, I have created this in Kotlin.

class FlutterLocalNotificationPluginRegistrant {

companion object {
    fun registerWith(registry: PluginRegistry) {
        if (alreadyRegisteredWith(registry)) {
            Log.d("Local Plugin", "Already Registered");
            return
        }
        FlutterLocalNotificationsPlugin.registerWith(registry.registrarFor("com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin"))
        Log.d("Local Plugin", "Registered");
    }

    private fun alreadyRegisteredWith(registry: PluginRegistry): Boolean {
        val key = FlutterLocalNotificationPluginRegistrant::class.java.canonicalName
        if (registry.hasPlugin(key)) {
            return true
        }
        registry.registrarFor(key)
        return false
    }
}}

Now create a Application class extending FlutterApplication and implement PluginRegistry.PluginRegistrantCallback.

class Application : FlutterApplication(), PluginRegistry.PluginRegistrantCallback {

override fun onCreate() {
    super.onCreate()
}

override fun registerWith(registry: PluginRegistry?) {
    if (registry != null) {
        FlutterLocalNotificationPluginRegistrant.registerWith(registry)
    }
}}

and register the Application class in the AndroidManifest.xml

<application
    android:name="com.packagename.Application"/>

All done. Now write a function to show notification and call it from the background handler method of Firebase messaging.

    Future _showNotificationWithDefaultSound(String title, String message) async {
  var androidPlatformChannelSpecifics = AndroidNotificationDetails(
      'channel_id', 'channel_name', 'channel_description',
      importance: Importance.Max, priority: Priority.High);
  var iOSPlatformChannelSpecifics = IOSNotificationDetails();
  var platformChannelSpecifics = NotificationDetails(
      androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
   await flutterLocalNotificationsPlugin.show(
    0,
    '$title',
    '$message',
    platformChannelSpecifics,
    payload: 'Default_Sound',
  );
}

and call it like this.

    Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {

  if (message['data'] != null) {
    final data = message['data'];

    final title = data['title'];
    final body = data['message'];

    await _showNotificationWithDefaultSound(title, message);
  }
  return Future<void>.value();
}

Solution 3

I have also faced this issue, So these are my learnings

In my Case : i am able to get notification in App-Resume or App-background state, but in App-Close state, I am not receiving notifification.

In this case our notification body was :

{notification: {body: null, title: null}, data: {body: hello, title: world}}

To Receive Notification in App-Closed state we changed notification to

{notification: {body: abc, title: abc}, data: {url: string, body: string, title: string}}
Share:
84,840
SlimenTN
Author by

SlimenTN

A software developer who is in love with programming I work on Web, desktop and mobile apps but I'm a big fan with web technologies and JS frameworks. I have recently worked on building a PHP framework based on MVC architecture: Github link: https://github.com/SlimenTN/Limpid Site: http://sbc.tn/limpid And for now I'm focusing on Angular framework and progressive web apps. Some things I did with love: Limpid (an MVC based PHP framwork) LogTrackerBundle (Symfony Bundle for tracking exception and logs) FlexiAnimate (JavaScript module for animating html DOMs based on the famous library Animate.css) SFCollectionAnalyze (JavaScript Module for generating templates for Symfony's CollectionType) Co-Developer of NotificationsBundle (Symfony Bundle based on Pusher API to provide realtime data broadcast) SlarnAutocomplete: Simple yet powerful autocomplete for Angular

Updated on July 09, 2022

Comments

  • SlimenTN
    SlimenTN almost 2 years

    I have built an application with flutter that works like a reminder.
    How can I display notifications to the user even though the app is closed?

  • SlimenTN
    SlimenTN over 5 years
    Thanks for your answer but in my case I don't want the notifications to be triggered by itself I want the app to show notifications based on some conditions, and to achieve this I need my app to work on background even tho it's closed.
  • PrakashKing
    PrakashKing over 5 years
    for that you need to have connected to backend databases like firebase, there you can manage notifications to send over internet.(to all users common/specific)
  • Dpedrinha
    Dpedrinha almost 5 years
    FlutterLocalNotificationsPlugin works very nicely. But I can't find how to "do something" when the scheduled notification fires off. Any idea?
  • Gautam Kumar
    Gautam Kumar over 4 years
    @SlimenTN Follow my solution, I have the same use case like yours. It's working!!!
  • krishnakumarcn
    krishnakumarcn over 4 years
    One question: Is this background message handler of firebase receive data messages even when the app is removed from recent list? If no, did you found any workaround for that??
  • Gautam Kumar
    Gautam Kumar over 4 years
    @KrishnakumarCN if you send only data object from FCM then you will receive data message in the background message handler, but if you also send notification object then FCM will automatically display the notification and then on click, you will get data message in onResume (if the app is in the background) or in on launch method (If app is not in the recent lists)
  • Gautam Kumar
    Gautam Kumar over 4 years
    I think the best way to handle notification in the background, is to let the FCM automatically display the notification from the notification object and on click fetch the data object in the ONLAUNCH OR ONRESUME method of the FCM.
  • Gautam Kumar
    Gautam Kumar about 4 years
    @MalekTubaisaht i will create a repository and update here
  • Gautam Kumar
    Gautam Kumar about 4 years
    @MalekTubaisaht Please check out this repository. Please do the FCM configuration part first. github.com/gssinghgautam/flutter_notification_demo.git
  • azheen
    azheen about 4 years
    can you share for java please instead of kotlin
  • Sajad Jaward
    Sajad Jaward about 4 years
    Can this be used for OneSignal as well?
  • ElLocoCocoLoco
    ElLocoCocoLoco over 2 years
    Any Working complete example working with flutter and Flutter Local Notifications Plugin to display notifications even if app is terminated?
  • Amr Ahmed
    Amr Ahmed over 2 years
    @SajadJaward I think the idea here rely on on registering the same operation on a native background side so yeah I think it's possible you just need to create a plugin registrant file relevant to the FirebaseCloudMessagingPluginRegistrant.kt with one signal plugin in it
  • Amr Ahmed
    Amr Ahmed over 2 years
    @MalekTubaisaht anything for the ios side?