Open In App

How to Add Local Notifications in Flutter?

Last Updated : 09 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

A push notification is a short message that appears as a pop-up on your desktop browser, mobile home screen, or in your device notification center from a mobile app. For receiving and showcasing push notifications in flutter using local_notifications. There are 3 conditions when we receive notifications

  1. When the app is closed.
  2. When the app is opened and the user is using it.
  3. When the app is not opened not it is completely closed. It is running in the background.

Here we will handle all the notifications.

Step By Step Implementation

Step 1: Create a Flutter project

flutter create .

Step 2: Add local notification package

// Add in dependencies in pubspec.yaml file
flutter_local_notifications:

 

Step 3: Create 1 class for adding all local notifications functions and add an Instance of local notification in it

Dart




class LocalNotificationService {
   // Instance of Flutternotification plugin
   static final FlutterLocalNotificationsPlugin _notificationsPlugin =
      FlutterLocalNotificationsPlugin();
}


 

Step 4: Add initialize function in this class

Dart




static void initialize() {
    // Initialization  setting for android
    const InitializationSettings initializationSettingsAndroid =
        InitializationSettings(
            android: AndroidInitializationSettings("@drawable/ic_launcher"));
    _notificationsPlugin.initialize(
      initializationSettingsAndroid,
      // to handle event when we receive notification
      onDidReceiveNotificationResponse: (details) {
        if (details.input != null) {}
      },
    );
  }



 

Step 5: Call this function in the Widget you are putting in the runApp function like this

Dart




Future main() async {
  runApp(const MyApp());
}
 
class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);
 
  @override
  State<MyApp> createState() => _MyAppState();
}
 
class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    // Initialise  localnotification
    LocalNotificationService.initialize();
  }
 
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}


 

Step 6: For handling all these conditions we have to add firebase messaging and  for this add firebase to your flutter project

To add firebase to your project read this article How to Add Firebase to Flutter App.

Dart




firebase_messaging:


 

Step 7: To handle background notifications add this to the main function

Dart




Future main() async {
  FirebaseMessaging.onBackgroundMessage(backgroundHandler);
  // To handle background message
  runApp(const MyApp());
}
 
// background handler
Future backgroundHandler(RemoteMessage msg) async {}


 

Step 8: Now to handle the other 2 conditions add this in the init function below initialization of local notification

Dart




@override
void initState() {
     
    super.initState();
 
    LocalNotificationService.initialize();
     
    // To initialise the sg
    FirebaseMessaging.instance.getInitialMessage().then((message) {
      
    });
     
    // To initialise when app is not terminated
    FirebaseMessaging.onMessage.listen((message) {
      if (message.notification != null) {
        LocalNotificationService.display(message);
      }
    });
     
    // To handle when app is open in
    // user divide and heshe is using it
    FirebaseMessaging.onMessageOpenedApp.listen((message) {
     print("on message opened app");
    });
  }



 

Step 9: To display notifications you have to add this function in the local notification

Dart




static Future<void> display(RemoteMessage message) async {
    // To display the notification in device
    try {
      print(message.notification!.android!.sound);
      final id = DateTime.now().millisecondsSinceEpoch ~/ 1000;
      NotificationDetails notificationDetails = NotificationDetails(
        android: AndroidNotificationDetails(
            message.notification!.android!.sound ?? "Channel Id",
            message.notification!.android!.sound ?? "Main Channel",
            groupKey: "gfg",
            color: Colors.green,
            importance: Importance.max,
            sound: RawResourceAndroidNotificationSound(
                message.notification!.android!.sound ?? "gfg"),
           
            // different sound for
            // different notification
            playSound: true,
            priority: Priority.high),
      );
      await _notificationsPlugin.show(id, message.notification?.title,
          message.notification?.body, notificationDetails,
          payload: message.data['route']);
    } catch (e) {
      debugPrint(e.toString());
    }


Also, add these settings to the android folder

1. Create a file named colors.xml in  android/app/src/main/res/values  and add these codes to this file

XML




<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <color name="green">#00FF00</color>
</resources>


2. Add this code in android/app/src/main/AndroidManifest.xml

XML




<meta-data android:name="com.google.firebase.messaging.default_notification_icon"
           android:resource="@drawable/ic_launcher">
<meta-data android:name="com.google.firebase.messaging.default_notification_color"
            android:resource="@color/green">


Note:

If you want to receive notifications you need 1 token which is unique for every phone and may expire in some time. You need to store this token in your server if you want to send notifications to individual people To get the token you can use this function of firebase messaging

Dart




// in some device or platform specially in web
// it may happen gettoken is not supported then
// you can put these condition to so that
// you can not get any error in production
var notifyToken = FirebaseMessaging.instance.isSupported()
                                            ? await FirebaseMessaging.instance
                                                .getToken()
                                            : "notifyToken";


Now you can receive notifications on your android phone. For receiving notifications on the web you have to do the following settings. Create this file in the web folder and named as firebase-messaging-sw.js

Javascript




 
   /*Update with yours config*/
  const firebaseConfig = {
   apiKey: "YOur Key-EW_U6NZU-A",
   authDomain: "flutter-notification-test-gfg.firebaseapp.com",
   projectId: "flutter-notification-tes-fec9d",
   storageBucket: "flutter-dsd-tes-fec9d.gfg.com",
   messagingSenderId: "263307381024",
   appId: "1:263307381024:web:dsds",
   measurementId: "G-dsada"
 };
  firebase.initializeApp(firebaseConfig);
  const messaging = firebase.messaging();
 
  /*messaging.onMessage((payload) => {
  console.log('Message received. ', payload);*/
  messaging.onBackgroundMessage(function(payload) {
    console.log('Received background message ', payload);
 
    const notificationTitle = payload.notification.title;
    const notificationOptions = {
      body: payload.notification.body,
    };
 
    self.registration.showNotification(notificationTitle,
      notificationOptions);
  });


3. Do the following changes in index.html

HTML




<!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8">
      <title>flutter_notification_test</title>
   </head>
   <body>
      <script>
           <!--Update with yours config-->
           const firebaseConfig = {
           apiKey: "your key-EW_U6NZU-A",
           authDomain: "flutter-notification-temp-fec9d.gfg.com",
           projectId: "flutter-notification-tes-fec9d",
           storageBucket: "flutter-dasdadas-tes-fec9d.appspot.com",
           messagingSenderId: "dasdsa",
           appId: "1:263307381024:web:dsadads",
           measurementId: "G-dsadsa"
         };
           firebase.initializeApp(firebaseConfig);
            
      </script>
      <script src="main.dart.js" type="application/javascript"></script>
      <script>
         if ("serviceWorker" in navigator) {
             window.addEventListener("load", function () {
               navigator.serviceWorker.register("/firebase-messaging-sw.js");
             });
           }
            
      </script>
   </body>
</html>


4. Add this function in location_notification_service.dart file in the lib folder

Dart




void messageListener(BuildContext context) {
    // Either you can pass buildcontext or you
      // can take a context from navigator key
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      print('Got a message in the foreground!');
      print('Message data: ${message.data}');
 
      if (message.notification != null) {
        print(
            'Message also contained a notification:  so it will pop up ${message.notification.body}');
        showDialog(
            context: context,
            // context: navigatorKey!.currentContext!,
            builder: ((BuildContext context) {
              return DynamicDialog(
                  title: message.notification.title,
                  body: message.notification.body);
            }));
      }
    });
  }


For dynamic dialog either add this code below localnotificationservice class file or create a new file 

Dart




import 'package:flutter/material.dart';
 
class DynamicDialog extends StatefulWidget {
  final title;
  final body;
  const DynamicDialog({this.title, this.body});
  @override
  _DynamicDialogState createState() => _DynamicDialogState();
}
 
class _DynamicDialogState extends State<DynamicDialog> {
  @override
  Widget build(BuildContext context) {
    // You can change the UI as per
    // your requirement or choice
    return AlertDialog(
      title: Text(widget.title),
      actions: <Widget>[
        OutlinedButton.icon(
            label: const Text('Close'),
            onPressed: () {
              Navigator.pop(context);
            },
            icon: const Icon(Icons.close))
      ],
      content: Text(widget.body),
    );
  }
}


Call these functions below the initialization of the local_notification service like this

Dart




@override
void initState() {
    super.initState();
    LocalNotificationService.initialize();
    LocalNotificationService.messageListener(context);
    FirebaseMessaging.onBackgroundMessage(backgroundHandler);
    FirebaseMessaging.instance.getInitialMessage().then((message) {
      print("Initial Message ${message.toString()}");
    });
    FirebaseMessaging.onMessageOpenedApp.listen((event) {
      print("Message on App opened ${event.toString()}");
    });
    FirebaseMessaging.onMessage.listen((event) {
      print("Message when it is termination mode ${event.toString()}");
      if (event.notification != null) {
        LocalNotificationService.display(event);
      }
    });
  }



 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads