Flutter Local Notifications: A Complete Guide

 

Flutter Local Notifications: A Complete Guide

Local notifications are a crucial feature for many apps, allowing users to receive alerts even when the app is not running. In this tutorial, we'll build a Flutter app that can show instant and scheduled notifications using the flutter_local_notifications package.


📂 Project Structure

Here's the structure of our Flutter project:

flutter_local_notifications_app/
│── android/
│── ios/
│── lib/
│   ├── main.dart
│   ├── homescreen.dart
│   ├── notification.dart
│── pubspec.yaml

🛠 Setting Up Dependencies

First, add the required dependencies to your pubspec.yaml file:

dependencies:
  flutter:
    sdk: flutter
  flutter_local_notifications: ^14.0.0
  timezone: ^0.9.2

Run flutter pub get to install the packages

🛠 Configure Android Manifest

For Android, you need to modify the AndroidManifest.xml file. Open android/app/src/main/AndroidManifest.xml and add the following permissions inside the <manifest> tag:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>


PART I. [Implementing Instant Notifications]

a. Initialize the Notification Plugin

Initialization is a crucial step to ensure that the notification plugin functions correctly in your Flutter app. This process involves setting up the FlutterLocalNotificationsPlugin, defining platform-specific settings, and making sure the app can handle notifications properly.

Here's how the initialization works:

  import 'package:flutter/material.dart';
  import 'package:flutter_local_notifications/flutter_local_notifications.dart';
  import 'package:notification_test_app/homescreen.dart';

  void main() {
     runApp(MyApp());
  }

  class MyApp extends StatefulWidget {
    const MyApp({super.key});

    @override
    _MyAppState createState() => _MyAppState();
  }

  class _MyAppState extends State<MyApp> {
    late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
    @override
    void initState() {
      super.initState();
      flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
      var initializationSettingsAndroid =
          AndroidInitializationSettings('@mipmap/ic_launcher');
      var initializationSettings = InitializationSettings(
        android: initializationSettingsAndroid,
      );
      flutterLocalNotificationsPlugin.initialize(initializationSettings);
    }

    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        home: Homescreen(),
      );
    }
  }

Understanding Initialization

FlutterLocalNotificationsPlugin Instance: This object is used to manage notifications     throughout the app.

1. Android-Specific Settings (AndroidInitializationSettings):   

        Uses @mipmap/ic_launcher as the default notification icon.

        Ensures notifications work on Android.

2. Initializing the Plugin:

       flutterLocalNotificationsPlugin.initialize(initializationSettings); prepares the plugin for use.

       Without initialization, notifications won’t function properly.

Why is Initialization Necessary?

    1. Ensures platform-specific configurations are set before displaying notifications.

    2. Prevents errors when trying to show or schedule notifications.

    3. Required to handle notification interactions, such as tapping on them to open specific screens.

With this setup, your app is ready to handle instant notificatons but not the scheduled notifications! 


b. Show an Instant Notification

Now that we have initialized the notification plugin, let's create a function to display an instant notification. This will allow users to trigger a notification immediately when they press a button.

Implementation

Create a new file notification.dart and add the following code:

  import 'package:flutter_local_notifications/flutter_local_notifications.dart';

  class ShowLocalNotification {
    //initialization
    final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
        FlutterLocalNotificationsPlugin();

    void shownotificaton(String title, String body) async {
      var android = AndroidNotificationDetails('channel id', 'channel NAME',
          priority: Priority.high, importance: Importance.max);
      var platform = NotificationDetails(
        android: android,
      );
      await flutterLocalNotificationsPlugin.show(0, title, body, platform,
          payload: 'Welcome to the Local Notification demo ');
    }

  }


Explanation

FlutterLocalNotificationsPlugin: This is the main class for managing notifications.

shownotificaton(String title, String body): This function takes a title and body text to display the notification.

AndroidNotificationDetails: This class defines how the notification will behave on Android devices:

Channel ID & Name: Required to categorize notifications.

Priority & Importance: Set to high and max to ensure notifications appear instantly.

NotificationDetails: Wraps platform-specific notification details.

shownotification: The function that actually triggers the notification.

Next Step

Now that we have a function to show instant notifications, let's integrate it into our UI so users can trigger notifications from a button click. Create homepage.dart and implement a function to show a notification:

  import 'package:flutter/material.dart';
  import 'package:notification_test_app/notification.dart';

  class Homescreen extends StatefulWidget {
    const Homescreen({super.key});

    @override
    State<Homescreen> createState() => _HomescreenState();
  }

  class _HomescreenState extends State<Homescreen> {
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        //show local notification flutter
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
             
              ElevatedButton(
                onPressed: () async {
                  ShowLocalNotification().shownotificaton(
                      'Local Notification', 'This is a local notification');
                },
                child: Text('Show Notification'),
              ),
            ],
          ),
        ),
      );
    }
  }


Now, run your app and press the Show Notification button. You should see a notification instantly!


PART II. [Implementing Instant Notifications]

🛠 Addition in Android Manifest file

Inside the <application> tag, add:

<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" android:exported="false"/>
<receiver android:name="com.dexterous.flutterlocalnotifications.ActionBroadcastReceiver" android:exported="false"/>
<receiver android:name="com.dexterous.flutterlocalnotifications.NotificationBroadcastReceiver" android:exported="false"/>

🛠 Addition in main.dart file


  import 'package:timezone/data/latest_all.dart' as tz;

  void main() {
    tz.initializeTimeZones(); // add this line to Ensure timezone initialization
    runApp(MyApp());
  }


To enable scheduled notifications, add this code in notification.dart 

 
  import 'package:timezone/data/latest.dart' as tz;
  import 'package:timezone/timezone.dart' as tz;

  class ShowLocalNotification {

    // add this constructor to initialize the timezone package
    ShowLocalNotification() {
      tz.initializeTimeZones(); // Initialize timezones when creating an instance
    }

    void scheduleNotification(String title, String body, int time) async {
      print("start");
      var android = AndroidNotificationDetails('channel id', 'channel NAME',
          priority: Priority.high, importance: Importance.max);
      var platform = NotificationDetails(
        android: android,
      );
      print("11111");
      await flutterLocalNotificationsPlugin.zonedSchedule(0, title, body,
          tz.TZDateTime.now(tz.local).add(Duration(seconds: time)), platform,

          // androidAllowWhileIdle: true,
          uiLocalNotificationDateInterpretation:
              UILocalNotificationDateInterpretation.absoluteTime,
          androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle);
      print("22222");
    }
  }


        
        const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                ShowLocalNotification().scheduleNotification(
                    'Local Notification test',
                    'This is a local notification after 5 sec interval',
                    5);
              },
              child: Text('Schedule Notification'),
            ),



Understanding Scheduled Notifications

tz.initializeTimeZones(): This function ensures that timezone data is properly set up, allowing notifications to be scheduled accurately even across different regions.

tz.TZDateTime.now(tz.local).add(Duration(seconds: time)): Retrieves the current time in the local timezone and adds the specified delay, ensuring the notification appears at the correct time.

zonedSchedule: Unlike normal scheduling methods, zonedSchedule ensures the notification is triggered in the appropriate timezone, preventing issues with daylight savings or incorrect time offsets.

androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle: Allows notifications to trigger even when the device is in a low-power idle state.

UILocalNotificationDateInterpretation.absoluteTime: Ensures that the scheduled time is treated as a fixed point rather than relative to system time changes.

Now, your scheduled notifications should work correctly and appear at the expected time! Modify homepage.dart to include a scheduling 

Now, pressing Schedule Notification will schedule a notification to appear after 5 seconds!

Conclusion

You have successfully built a Flutter app with local notifications! 🎉

Instant Notifications: Show notifications immediately.

Scheduled Notifications: Set up notifications to appear later.

Try adding more features like custom sounds, big text notifications, or actions on click. Happy coding! 🚀



Post a Comment

Previous Post Next Post