Local Notifications in Flutter - Notify Users with Minimal Effort

Learn how to implement local notifications into both Android and iOS using flutter_local_notifications plugin

thecodexhub
7 min readNov 17, 2021
Photo by Jonas Leupe on Unsplash

Notifications are an integral way to convey some information to the users when outside the app. They are aimed to improve user experience and help draw users’ attention and drive their engagement with the app.

Local notifications give you the ability to alert your users at times when your app might not be running either in background or foreground. You schedule reminders and then the system takes on the responsibility of delivering the notification for the same at the appropriate time.

When it comes to mobile applications, there are two types of notifications - Local notification and Remote notification.

Local notifications are scheduled by an app locally and delivered by the same device.

Remote notifications are sent by a remote server (its provider) which sends some information to devices where the app is installed.

In this article, we are going to learn how to implement local notifications into both Android and iOS using Flutter.

Add dependency to the Flutter app

First of all, we need to add a dependency flutter_local_notifications in the pubspec.yaml file. For this tutorial, I am going to use version 9.1.2 in the example project.

pubspec.yaml file

Now, we will create a new dart file, notification_service.dart that contains a service class NotificationService. This class will be responsible for handling all the notification logic, initialization code and eventually expose methods to create, send, schedule and cancel notifications.

NotificationService class

Here we are using the Singleton pattern to create the service class. We have also created an instance of FlutterLocalNotificationsPlugin.

Setup platform-specific initialization settings

Since Flutter is a cross-platform framework, some platform-specific implementations need to be configured when using this local notification package.

Setup android initialization settings

To configure android initialization settings, only a single argument needs to be passed, and that is defaultIcon, that resides inside the drawable folder. This is needed to display the icon in the notification bar.

The full path for the app icon is:

PROJECT_NAME\android\app\src\main\res\drawable\APP_ICON.png

Setup iOS initialization settings

Here the configuration is a little bit complex. First start with adding the following couple of lines to the didFinishLaunchingWithOptions method in the AppDelegate.swift file of your iOS project.

Now, our AppDelegate.swift file should look like this:

It is also important to request some permissions from users regarding issues related to notifications. The IOSInitializationSettings object takes in three arguments: requestSoundPermission, requestBadgePermission and requestAlertPermission.

Depending upon your requirement, you can set all of them to false initially and at a later stage you can ask for the permission for those from the users by calling requestIOSPermissions method.

Create the InitializationSettings object

Let’s walk through how we can create an InitializationSettings object. The plugin is used to initialize platform-specific initialization settings for Android, iOS and macOS platforms.

Now wrap up all the configuration logic for platform-specific initialization settings inside a method called init, which will be called from our main.dart file upon app launch.

Here, the initialize method is called on the FlutterLocalNotificationsPlugin object. This takes two arguments, one is InitializationSettings object that we have already passed and another is onSelectNotification property.

This optional property represents a callback that will be triggered once a notification has been tapped by the user. This callback has one argument called payload of type String that holds the data passed through the notification.

In our case, the callback function triggers navigation to DetailsPage with the contents from the payload associated with the notification.

Our init method should look like this now:

It’s time to call the init method back into our main function inside main.dart and also the requestIOSPermissions method to request permissions from iOS users as soon as the app starts.

Display a notification

To display a notification, we have to specify some configuration regarding platform-specific NotificationDetails instance, that takes in different arguments that are unique to the platform.

AndroidNotificationDetails handles the required configurations for Android devices. It takes in several arguments like channelId, channelName, channelDescription, playSound, priority, importance etc. An instance of AndroidNotificationDetails looks like:

IOSNotificationDetails similarly handles notification configurations in iOS devices and takes in presentAlert, presentBadge, badgeNumber, sound, subtitle etc. as the arguments. An instance of IOSNotificationDetails looks like:

Next step is to create an object NotificationDetails that expects the platform-specific notification details as the arguments.

Now we need to call the show method of FlutterLocalNotificationsPlugin. This method is responsible for showing the local notification in the end user device and it takes in some arguments id, title, body, notificationDetails and payload.

Wrap the method and the logic inside a function named showNotification so that it becomes easy to call the function from anywhere in our app to display a notification.

Schedule a notification

To schedule a notification, a zonedSchedule method is provided that expects an instance of the TZDateTime class provided by the timezone package.

As the flutter_local_notifications plugin already depends upon the timezone package, it is not necessary to add the timezone package as direct dependency. In other words, the timezone package will be a transitive dependency.

Usage of the timezone package requires initialization. Import it into notification_service.dart file and initialize time zone.

The zonedSchedule method expects some arguments including id, title, body, scheduleDate, notificationDetails, payload, androidAllowWhileIdle, uiLocalNotificationDateInterpretation, matchDateTimeComponents etc.

The scheduleDate parameter tells when the notification will be displayed.

The uiLocalNotificationDateInterpretation is used in iOS versions below 10 to determine if the scheduled date should be interpreted as absolute time or wall clock time.

If a value for matchDateTimeComponents parameter is given, this tells the plugin to schedule a recurring notification that matches the specified date and time components. Specifying DateTimeComponents.time would result in a daily notification at the same time.

And androidAllowWhileIdle is in Android to determine if the notification should be delivered at the specified time even when the device is in a low-power idle mode.

Let’s wrap up all the logic inside a function named scheduleNotification so that it becomes easy to schedule a notification from anywhere in our app.

Cancel a notification

While cancelling a notification, you can either cancel a particular notification or you can cancel all the pending notifications.

Cancel a single notification

To cancel a single notification, let’s create a new function cancelNotification that will call the cancel method from the FlutterLocalNotificationsPlugin object. This function expects an id which is the ID for that specific notification.

Cancel all notifications

To cancel all the pending notifications, let’s create another function cancelAllNotifications that will be responsible to call cancelAll method from the FlutterLocalNotificationsPlugin object.

Unlike the previous cancel method, cancelAll doesn’t require any argument.

Here we go. We have done all the necessary steps. Now you only need to add these functionalities in your app.

If you want to get the full code from this tutorial with a fully functional app, below is the link to the GitHub repository. Clone the repository and run in your computer with an emulator.

Conclusion

This article has covered everything you need to know to configure platform-specific initialization settings for flutter_local_notifications package and to create, send, schedule and cancel notifications.

I hope this blog will provide you sufficient knowledge to use it in your own projects. If you have any query or suggestions, let me know in the comments.

Don’t forget to clap 👏 if this article really helps you and teaches you something new. Actually you know you can click that clap button 50 times. Try it out.😅

Thanks for reading. Happy coding!

--

--

thecodexhub

Passionate Flutter Developer from INDIA || Technical Content Creator || Instagram: @thecodexhub