With the advent of the mobile app era, it's now crucial, more than ever, to keep users engaged. One way of doing so is by using local notifications. Yet what if we introduce Flutter into the equation? This cross-platform framework allows developers to create native mobile applications for both iOS and Android from a single codebase.
Now, implementing local notifications in a Flutter app just brings that functionality to the next level. In this blog post, we aim to cover everything you need to know about using local notifications in Flutter. So sit tight and have an enjoyable experience as you venture into the world of Flutter local notifications.
Before we hop into the world of local notifications in Flutter, we need to set up our development environment. You will need Flutter SDK and a code editor. You can use any code editor you like. However, for the sake of this tutorial, we shall use VS Code or Android Studio.
With your environment set up, it's time we delve deeper to understand the Flutter local notification and Flutter get plugin which will empower us to realize our goal of adding local notifications to our Flutter app.
Local notifications, unlike their counterpart push notifications, originate on the user's device rather than being sent from a remote server. They work even when the app is closed or the device is in low-power idle mode. Putting it in the context of Flutter, the flutter_local_notifications package enables us to implement local notifications effectively.
Now, let's add the local notifications plugin to the newly created Flutter project.
To achieve this, open up your pubspec.yaml file and add the line flutter_local_notifications: ^4.0.1+2 under dependencies. This effectively sets up the local notification package as a dependency.
Following the addition, refresh your dependencies list by running flutter pub get once more.
1 dependencies: 2 flutter_local_notifications: ^4.0.1+2 3
The code above makes the project aware of the local notification plugin and, thus, the first step towards displaying local notifications in our Flutter app.
Post this, you run flutter pub get in the terminal. This command is responsible for downloading the necessary packages that our application needs, this time being the Flutter local notifications plugin.
1 flutter pub get 2
You have now successfully installed the local notifications plugin.
A new Flutter project needs to be set up for the purpose of this blog. Run the following command in your terminal to create one:
1 flutter create local_notifications_demo 2
This step leads to the generation of a new Flutter project named local_notifications_demo. Navigate into the new directory where you can explore the default code of your new Flutter app.
When it comes to interacting with the user's Operating System for sending local notifications, we need to ensure that the user has provided the necessary permissions.
Firstly, let's focus on Android devices. To configure Android for receiving local notifications, we need to set certain platform-specific initialization settings.
Open your AndroidManifest.xml file and add the following lines:
1 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> 2 <uses-permission android:name="android.permission.VIBRATE" /> 3
The above code sets the essential permissions for Android notifications.
With this, we take a step closer to our goal of executing local notifications on Android. This initialization is mandatory for each Android device and will serve as default values for your app.
In iOS, the user is asked to grant permission for receiving notifications from the app during the app launch. You can request permissions at your preferred point in your app as well.
For scheduling notifications, you will have to add the following lines to your Info.plist file:
1 <key>UIBackgroundModes</key> 2 <array> 3 <string>fetch</string> 4 <string>remote-notification</string> 5 </array> 6
This piece of code requests permission to schedule notifications when the app is not running in the foreground. This will make sure the local notifications are sent even when the app is not active.
With this, we have successfully managed app permissions, both for Android and iOS, to employ local notifications.
Before we proceed with creating local notifications, let's understand an essential aspect of local notifications, which is the notification payload. When displaying a local notification, we can attach an additional string of information, often called a 'payload'. This payload helps perform specific tasks when a user interacts with the notification.
For instance, consider a scenario where a user receives a notification about a new chat message. The payload might contain the chat id, which can drive the app to open the specific chat screen when the user taps on the notification.
Now that we understand what a notification payload is, let's hop onto the journey of creating local notifications.
To create local notifications, we need to create instances of the NotificationDetails class for both Android and iOS using platform-specific constructors (i.e. AndroidNotificationDetails and IOSNotificationDetails). These constructors take in parameters like the notification id, title, and body.
In the body of the notification, we detail what the notification is all about. It is within this NotificationDetails instance that we can define how we want the notification to look and when we want it to appear.
Here is where the schedule method comes in: by calling it, we can schedule notifications to display at a particular point in time.
Once our NotificationDetails instance is ready, it's time for us to show the notification!
Continuing with the creation of local notifications, the example below showcases how you can go about it:
1 // Create Notification 2 Future<void> _showNotification() async { 3 var androidPlatformChannelSpecifics = AndroidNotificationDetails( 4 'channel_ID', 5 'channel_name', 6 'channel_description', 7 importance: Importance.max, 8 priority: Priority.high, 9 ); 10 var iOSPlatformChannelSpecifics = IOSNotificationDetails(); 11 var platformChannelSpecifics = NotificationDetails( 12 android: androidPlatformChannelSpecifics, 13 iOS: iOSPlatformChannelSpecifics, 14 ); 15 await flutterLocalNotificationsPlugin.show( 16 0, 17 'Test Title', 18 'Test Body', 19 platformChannelSpecifics, 20 payload: 'Test Payload', 21 ); 22 } 23
This function generates a notification with the title 'Test Title' and body 'Test Body'. The notification is scheduled to display instantly due to the invocation of the show() method.
When a notification pops up and the user taps on it, the desired action in the application needs to occur. For instance, let's say we want to direct the user to a certain page in our app. To accomplish this, we need to use the selectNotification() callback, which gathers the payload and prompts the associated action.
The following code snippet outlines how we can implement this:
1 final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = 2 FlutterLocalNotificationsPlugin(); 3 const AndroidInitializationSettings initializationSettingsAndroid = 4 AndroidInitializationSettings('app_icon'); 5 final IOSInitializationSettings initializationSettingsIOS = 6 IOSInitializationSettings( 7 onDidReceiveLocalNotification: onDidReceiveLocalNotification); 8 final InitializationSettings initializationSettings = InitializationSettings( 9 android: initializationSettingsAndroid, 10 iOS: initializationSettingsIOS); 11 await flutterLocalNotificationsPlugin.initialize(initializationSettings, 12 onSelectNotification: selectNotification); 13
In the above code, initializationSettings refers to the platform-specific initialization settings we previously mentioned, which now comprise of AndroidInitializationSettings and IOSInitializationSettings. Notice onDidReceiveLocalNotification, our callback method. It helps in handling the local notification received when the app is in the foreground.
The selectNotification() works when the user has interacted with the notification. This function, like onDidReceiveLocalNotification, is called with the payload string as its argument. We can now use this payload to decide which screen to navigate to or what other tasks to perform.
That's it! You are now acquainted with receiving notifications, handling them, and directing the user to the appropriate point within your app when taping on a notification.
One of the most crucial aspects to keep in mind while creating local notifications is what should happen when users tap on the notification. The actions you introduce at this point will determine a lot about user impressions and experiences of your app.
In most cases, you would want to direct the users to a specific screen of your app when they tap on a notification. This is where the notification payload comes into play. When invoking the show or schedule methods, you can add an additional "payload" parameter. This payload is nothing but a simple string that you can use to encode any additional data that you want to be attached to the notification. This could be something as simple as an identifier for the screen you want to open.
Then, inside your navigation code, you can use a switch or if-else logic to check the payload attached to a notification and navigate to the appropriate screen.
Sometimes, a tap on a notification might not just direct users to a specific screen, but also trigger additional actions like fetching data from the server or updating some local state.
Again, the payload comes in handy here. For example, suppose you have a chat application and you send a notification with the message id as the payload. When the user taps on the notification, you can use this message id to fetch the full message object from your server and display it on the chat screen.
The callback that handles these actions is defined during the initialization of the local notifications plugin. The following is the sample code:
1 // Initializes the plugin and handles the actions when a user taps on a notification 2 await flutterLocalNotificationsPlugin.initialize( 3 InitializationSettings( 4 android: AndroidInitializationSettings('app_icon'), 5 iOS: IOSInitializationSettings(), 6 ), 7 onSelectNotification: handleNotificationTapped, 8 ); 9
In the above code, the handleNotificationTapped function will be invoked when a user taps on a local notification. It takes the payload string as an argument, which you can use to determine the screen to navigate to or any other actions that need to be performed.
Managing the action associated with tapping on the local notification is crucial. It can dramatically enhance the user experience and make your notifications significantly more effective.
It is possible to encounter challenges while incorporating local notifications. These can range from failure in getting the expected output to the local notifications not appearing. Here are a few common issues and their potential solutions:
Local Notifications not appearing: After setting everything up correctly, you might still find your notifications not showing up. This situation could arise from not granting the necessary permissions for the app to show notifications. Please double-check the permission settings as defined previously in this article, both on your device and within your app's settings.
Notifications not opening the app: If tapping on the notifications does not lead the user to the intended screen, ensure the selectNotification() function has been properly set during initialization.
Scheduled Notifications not working as intended: It can often be tricky to set the time for displaying scheduled notifications. If you find your notifications not popping up at the expected time, please cross-verify your logic for calculating the time.
Remember, the best way to see if the local notifications work correctly is by testing them on a real device as some of these features might not function as intended in emulators.
Use Correct Naming Convention: Since other developers may read your code, following Dart-specific conventions for naming classes, methods, variables, and constants plays a pivotal role in enhancing code readability.
Use Constants: If some values, like default preferences or hard-coded strings, are used frequently, it's better to declare them as constants.
Comment your code: Add comments to your functions and complex logic. These play a critical role in enhancing code readability and maintainability in the long run.
Avoid Nested Schedules: While scheduling notifications, try to calculate the required delay and call the schedule() method once rather than nesting Future.delayed() inside schedule.
Efficient use of Plugins: While the Flutter local notifications plugin is powerful, ensure you use it judiciously to avoid draining the users' device battery.
These tips not only hold good for coding local notifications in Flutter but are broadly applicable across all code you will write.
And there you have it! A complete and comprehensive guide on incorporating local notifications steadfastly into your Flutter app! By deftly engaging the flutter_local_notifications plugin, you can efficiently enhance user engagement and app retention measures. This technique of displaying local notifications is just one of the many capabilities that make Flutter a leading choice among cross-platform frameworks. So continue exploring, keep learning, and keep Fluttering!
Remember that incorporating local notifications into your Flutter app significantly boosts your application's user interactivity, keeping users engaged even when your app is not running in the foreground. Flutter truly encapsulates the future of mobile application development, so don't hesitate to dive in and get your hands dirty with writing Flutter apps.
As always, happy coding to all the devoted devs out there!
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.