Local Notifications in Flutter

By | July 4, 2020

Hello everyone,
In this article we will learn how to show local notifications in Flutter.


Local Notifications in Flutter


What we are going to learn?

  • Show Simple notifications
  • Show Repeated Notifications
  • Show Scheduled Notifications
  • Show Notifications at a particular time and day of a week
  • Show Notification with an attachment
  • Show Notifications with HTML content
  • Cancel a Notification.
  • Cancel all Notifications
  • Deal with Notification Taps.

So Let’s start…

Watch Video Tutorial


Add Dependencies

Open your pubspec.yaml file and add the below in the dependencies

flutter_local_notifications: ^1.4.4+1
// Add below dependencies based on your requirement
rxdart: ^0.24.1
path_provider: ^1.6.11
http: ^0.12.1
...

For the initial Android and iOS setup, please follow this link.
Once you have done the setup, let’s move to the flutter coding part.
For this example, I am keeping most of my notifications related code in a separate file. So let’s create a new file named “NotificationPlugin.dart”.
First thing I will need is a handle to the notifications plugin.

FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;

Get Permission from the User

Next is to get the permission from the user. This permission is needed only in iOS and not in Android.

_requestIOSPermission() {
    flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
            IOSFlutterLocalNotificationsPlugin>()
        .requestPermissions(
          alert: false,
          badge: true,
          sound: true,
        );
 }

iOS Notifications


Let’s assume the user taps allow.
Great, now we have the permission from the user.
Now let’s initialize the settings for notifications.

initializePlatformSpecifics() {
    var initializationSettingsAndroid =
        AndroidInitializationSettings('app_notf_icon');
    var initializationSettingsIOS = IOSInitializationSettings(
      requestAlertPermission: true,
      requestBadgePermission: true,
      requestSoundPermission: false,
      onDidReceiveLocalNotification: (id, title, body, payload) async {
        // your call back to the UI
      },
    );
initializationSettings = InitializationSettings(
        initializationSettingsAndroid, initializationSettingsIOS);
}

‘app_notf_icon’ is the icon created inside the android Studio, I am explaining the same in the above youtube video. Once you have that icon, make sure to copy in the Android res/drawable folder. Now we are good with Android Notification Settings.
Next for iOS, as in the above code for requestAlertPermission, requestBadgePermission and requestSoundPermission set it to how you want.”onDidReceiveLocalNotification” is for iOS versions less than 10. It will be triggered when the. app is running in foreground and when a notification is triggered. In versions less than 10, there wont be any notification appearing when it is triggered when the application is running in foreground.
So how to get the callbacks above version 10?
Here is the way to do it…

await flutterLocalNotificationsPlugin.initialize(initializationSettings,
        onSelectNotification: (String payload) async {
      onNotificationClick(payload);    // your call back to the UI
});

Let’s jump into the main part…
The Notifications ….


Simple Notification

Future<void> showNotification() async {
    var androidChannelSpecifics = AndroidNotificationDetails(
      'CHANNEL_ID',
      'CHANNEL_NAME',
      "CHANNEL_DESCRIPTION",
      importance: Importance.Max,
      priority: Priority.High,
      playSound: true,
      timeoutAfter: 5000,
      styleInformation: DefaultStyleInformation(true, true),
    );
    var iosChannelSpecifics = IOSNotificationDetails();
    var platformChannelSpecifics =
        NotificationDetails(androidChannelSpecifics, iosChannelSpecifics);
    await flutterLocalNotificationsPlugin.show(
      0,  // Notification ID
      'Test Title', // Notification Title
      'Test Body', // Notification Body, set as null to remove the body
      platformChannelSpecifics,
      payload: 'New Payload', // Notification Payload
    );
}

Here for Android Channel Specifications, if you have set some settings for that channel ID, it wont change after that, But you can trigger further notifications on that channel with new Notification ID, Title, Body and Payload. You may have to change the channel ID or reinstall the app to reset it.


Set

importance: Importance.Max,
priority: Priority.High,

to show the notification as popup on the top of the screen. Otherwise it will be triggered but wont show up on top of the screen, instead it will be there in the Android Notification area.

Local Notification in Flutter

Schedule a Notification

Future<void> scheduleNotification() async {
    var scheduleNotificationDateTime = DateTime.now().add(Duration(seconds: 5));
    var androidChannelSpecifics = AndroidNotificationDetails(
      'CHANNEL_ID 1',
      'CHANNEL_NAME 1',
      "CHANNEL_DESCRIPTION 1",
      icon: 'secondary_icon',
      sound: RawResourceAndroidNotificationSound('my_sound'),
      largeIcon: DrawableResourceAndroidBitmap('large_notf_icon'),
      enableLights: true,
      color: const Color.fromARGB(255, 255, 0, 0),
      ledColor: const Color.fromARGB(255, 255, 0, 0),
      ledOnMs: 1000,
      ledOffMs: 500,
      importance: Importance.Max,
      priority: Priority.High,
      playSound: true,
      timeoutAfter: 5000,
      styleInformation: DefaultStyleInformation(true, true),
    );
    var iosChannelSpecifics = IOSNotificationDetails(
      sound: 'my_sound.aiff',
    );
    var platformChannelSpecifics = NotificationDetails(
      androidChannelSpecifics,
      iosChannelSpecifics,
    );
    await flutterLocalNotificationsPlugin.schedule(
      0,
      'Test Title',
      'Test Body',
      scheduleNotificationDateTime,
      platformChannelSpecifics,
      payload: 'Test Payload',
    );
  }

This notification will be triggered 5 seconds from when it is triggered and it’s going to dismiss after 5 seconds if the user is not interacting with it.


Show Notification Daily at a time

Future<void> showDailyAtTime() async {
    var time = Time(18, 0, 0);
    var androidChannelSpecifics = AndroidNotificationDetails(
      'CHANNEL_ID 4',
      'CHANNEL_NAME 4',
      "CHANNEL_DESCRIPTION 4",
      importance: Importance.Max,
      priority: Priority.High,
    );
    var iosChannelSpecifics = IOSNotificationDetails();
    var platformChannelSpecifics =
        NotificationDetails(androidChannelSpecifics, iosChannelSpecifics);
    await flutterLocalNotificationsPlugin.showDailyAtTime(
      0,
      'Test Title at ${time.hour}:${time.minute}.${time.second}',
      'Test Body', //null
      time,
      platformChannelSpecifics,
      payload: 'Test Payload',
    );
 }

The above notification is going to be fired at exactly 6 PM everyday.


Show Weekly at Day and Time

Future<void> showWeeklyAtDayTime() async {
    var time = Time(10, 0, 0);
    var androidChannelSpecifics = AndroidNotificationDetails(
      'CHANNEL_ID 5',
      'CHANNEL_NAME 5',
      "CHANNEL_DESCRIPTION 5",
      importance: Importance.Max,
      priority: Priority.High,
    );
    var iosChannelSpecifics = IOSNotificationDetails();
    var platformChannelSpecifics =
        NotificationDetails(androidChannelSpecifics, iosChannelSpecifics);
    await flutterLocalNotificationsPlugin.showWeeklyAtDayAndTime(
      0,
      'Test Title at ${time.hour}:${time.minute}.${time.second}',
      'Test Body', //null
      Day.Saturday,
      time,
      platformChannelSpecifics,
      payload: 'Test Payload',
    );
  }

The above notification is going to fire at exactly 10 AM on every Saturday.


Repeated Notifications

Future<void> repeatNotification() async {
    var androidChannelSpecifics = AndroidNotificationDetails(
      'CHANNEL_ID 3',
      'CHANNEL_NAME 3',
      "CHANNEL_DESCRIPTION 3",
      importance: Importance.Max,
      priority: Priority.High,
      styleInformation: DefaultStyleInformation(true, true),
    );
    var iosChannelSpecifics = IOSNotificationDetails();
    var platformChannelSpecifics =
        NotificationDetails(androidChannelSpecifics, iosChannelSpecifics);
    await flutterLocalNotificationsPlugin.periodicallyShow(
      0,
      'Repeating Test Title',
      'Repeating Test Body',
      RepeatInterval.EveryMinute,
      platformChannelSpecifics,
      payload: 'Test Payload',
    );
  }

This notification is going to be repeated every minute.


Show Notification with Attachment

Future<void> showNotificationWithAttachment() async {
    var attachmentPicturePath = await _downloadAndSaveFile(
        'https://via.placeholder.com/800x200', 'attachment_img.jpg');
    var iOSPlatformSpecifics = IOSNotificationDetails(
      attachments: [IOSNotificationAttachment(attachmentPicturePath)],
    );
    var bigPictureStyleInformation = BigPictureStyleInformation(
      FilePathAndroidBitmap(attachmentPicturePath),
      contentTitle: '<b>Attached Image</b>',
      htmlFormatContentTitle: true,
      summaryText: 'Test Image',
      htmlFormatSummaryText: true,
    );
    var androidChannelSpecifics = AndroidNotificationDetails(
      'CHANNEL ID 2',
      'CHANNEL NAME 2',
      'CHANNEL DESCRIPTION 2',
      importance: Importance.High,
      priority: Priority.High,
      styleInformation: bigPictureStyleInformation,
    );
    var notificationDetails =
        NotificationDetails(androidChannelSpecifics, iOSPlatformSpecifics);
    await flutterLocalNotificationsPlugin.show(
      0,
      'Title with attachment',
      'Body with Attachment',
      notificationDetails,
    );
}

_downloadAndSaveFile(String url, String fileName) async {
    var directory = await getApplicationDocumentsDirectory();
    var filePath = '${directory.path}/$fileName';
    var response = await http.get(url);
    var file = File(filePath);
    await file.writeAsBytes(response.bodyBytes);
    return filePath;
}

In this example, the notification will download an image from the specified URL and set it in the attachments for Android and iOS.


Get Pending Notifications

Future<int> getPendingNotificationCount() async {
    List<PendingNotificationRequest> p =
        await flutterLocalNotificationsPlugin.pendingNotificationRequests();
    return p.length;
}

This will return the number. of notifications that are yet to be fired.


Cancelling Notifications

Future<void> cancelNotification() async {
    await flutterLocalNotificationsPlugin.cancel(0);
}
Future<void> cancelAllNotification() async {
    await flutterLocalNotificationsPlugin.cancelAll();
}

cancel(0) will cancel the notification with ID = 0
cancelAll() will cancel all the notifications.


Complete Source code link is here.
https://bitbucket.org/vipinvijayan1987/tutorialprojects/src/LocalNotifications/FlutterTutorialProjects/flutter_demos/


There are many other things that you can do with the flutter notifications plugin. These were the basic stuff that you will frequently use.
So that’s it.

Please leave your valuable comments below.

Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *