Open In App

How to Add Local Notifications in Flutter?

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




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

 

Step 4: Add initialize function in this class




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




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.




firebase_messaging:

 

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




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




@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




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 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




<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




// 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




 
   /*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




<!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8">
      <title>flutter_notification_test</title>
      <script src="https://www.gstatic.com/firebasejs/8.4.1/firebase-app.js"></script>
   </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




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 




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




@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);
      }
    });
  }


 


Article Tags :