How to Push Local Notification with Firebase in Flutter

In this example, we are going to show you how to push local notifications using Firebase Cloud Messaging (FCM) in Flutter App. We will push notification with REST API using cURL from PHP, Node.js to push the notification.

Before starting, follow these steps:

  1. Try: How to show Local Notification in Flutter App. 
  2.  Integrate Firebase into your project

After integrating Firebase in your project, add firebase_core, firebase_messaging and awesome_notifications packages in your project by adding following lines in pubspec.yaml file.

dependencies:
  flutter:
    sdk: flutter
  awesome_notifications: ^0.6.19
  firebase_core: ^1.10.6
  firebase_messaging: ^11.2.4

In main() method of main.dart file, you have initialized Firebase, Firebase Cloud Messaging, and Local Notification like below:

import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';

void main() async {
   WidgetsFlutterBinding.ensureInitialized();

   AwesomeNotifications().initialize(
     'resource://drawable/notification_icon', 
     [            // notification icon 
        NotificationChannel(
            channelGroupKey: 'basic_test',
            channelKey: 'basic',
            channelName: 'Basic notifications',
            channelDescription: 'Notification channel for basic tests',
            channelShowBadge: true,
            importance: NotificationImportance.High, 
        ),
        //add more notification type with different configuration

     ]
   );

  //click listiner on local notification
  AwesomeNotifications().actionStream.listen((ReceivedNotification receivedNotification){
     print(receivedNotification.payload!['title']);
     //output from local notification click.
  });

  await Firebase.initializeApp(); //initilization of Firebase app
  FirebaseMessaging.instance.subscribeToTopic("all"); //subscribe firebase message on topic

  FirebaseMessaging.onBackgroundMessage(firebaseBackgroundMessage);
  //background message listiner 
  
  runApp(MyApp());

}

Here, the most important things is FirebaseMessaging.instance.subscribeToTopic("all");

This is the subscription to the topic named "all", where we will send the notification with REST API. The device where this topic is subscribed only gets the message. If you want to send messages to specific devices only, create a different topic like in the REST API explained below and subscribe accordingly.

Here, FirebaseMessaging.onBackgroundMessage(firebaseBackgroundMessage); is used to listen to messages in the background and foreground, this method will not be triggered when the app is active. firebaseBackgroundMessage is a global method that is called on message received.

Future<void> firebaseBackgroundMessage(RemoteMessage message) async {
    print(message.data);
    AwesomeNotifications().createNotification(
        content: NotificationContent( //with image from URL
            id: 1,
            channelKey: 'basic', //channel configuration key
            title: message.data["title"],
            body: message.data["body"],
            bigPicture: message.data["image"],
            notificationLayout: NotificationLayout.BigPicture,
            payload: {"name":"flutter"}
        )
    );
}

You can put the following listener in initState to receive messages when the app is active.

FirebaseMessaging.onMessage.listen(firebaseBackgroundMessage); 

The full code of the flutter app will look like below.

import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';

void main() async {
   WidgetsFlutterBinding.ensureInitialized();

   AwesomeNotifications().initialize(
     'resource://drawable/notification_icon', 
     [            // notification icon 
        NotificationChannel(
            channelGroupKey: 'basic_test',
            channelKey: 'basic',
            channelName: 'Basic notifications',
            channelDescription: 'Notification channel for basic tests',
            channelShowBadge: true,
            importance: NotificationImportance.High, 
        ),
        //add more notification type with different configuration

     ]
   );

  //click listiner on local notification
  AwesomeNotifications().actionStream.listen((ReceivedNotification receivedNotification){
     print(receivedNotification.payload!['title']);
     //output from local notification click.
  });

  await Firebase.initializeApp(); //initilization of Firebase app
  FirebaseMessaging.instance.subscribeToTopic("all"); //subscribe firebase message on topic

  FirebaseMessaging.onBackgroundMessage(firebaseBackgroundMessage);
  //background message listiner 
  
  runApp(MyApp());

}

// Declared as global, outside of any class
Future<void> firebaseBackgroundMessage(RemoteMessage message) async {
    AwesomeNotifications().createNotification(
        content: NotificationContent( //with image from URL
            id: 1,
            channelKey: 'basic', //channel configuration key
            title: message.data["title"],
            body: message.data["body"],
            bigPicture: message.data["image"],
            notificationLayout: NotificationLayout.BigPicture,
            payload: {"name":"flutter"}
        )
    );
}

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
     return MaterialApp(
         home: Home()
      );
  }
}

class Home extends  StatefulWidget {
  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  
  @override
  void initState() {
    FirebaseMessaging.onMessage.listen(firebaseBackgroundMessage); 
    //active app listiner.
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        
    );
  } 
}

Remember: Do not use Firebase Console to trigger push notifications, because two local notifications will appear, one from Firebase itself, and from Awesome notifications. It is caused because the Firebase Console sends "notification" data too, which is used by Firebase internally in App to show a local notification.

Now it's time to trigger the message from REST API. You can send the REST API request in the following format:

POST URL: https://fcm.googleapis.com/fcm/send

Content-Type: application/json
Authorization: server_key
{
	"to": "topics/all",
	"data": {
		"title": "title",
		"body": "body text",
		"image": "image all"
	}
}

Remember: Do not send "notification" values, otherwise, you will get two local notifications, the reason for duplicate local notification is explained above.

Here, "to" is used to assign the topic, which can also be used by the Firebase message listeners to get the message. You can create different topics to send to a specific device or to some group of devices. You can subscribe with the following code:

FirebaseMessaging.instance.subscribeToTopic("all");

To get the server key of Firebase cloud messaging, go to Project > Project Setting > Cloud Messaging: 

Now it's time to send messages using REST API, We are using cURL with PHP, you can use node.js or any other language to send messages. 

<?php
$url = 'https://fcm.googleapis.com/fcm/send';
$serverkey = 'servver key';

$fields = array(
	  'to' => "/topics/all", //target topic recievers
	  'data' => array(
			       'title'=>'Welcome to FlutterCampus',
					'body'=>"Hello this notification is from Flutter App.",
					'image'=>'https://www.fluttercampus.com/img/uploads/web/2021/02/c4ca4238a0b923820dcc509a6f75849b.webp'
	        )
);

$headers = array('Authorization:key='.$serverkey,'Content-Type:application/json');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
if ($result) {
  echo "success";
}else{
  die('Curl failed: ' . curl_error($ch));
}
curl_close($ch);

?>

Now, run this PHP code in your server, you will get the notification in your app. The output or local notification will look like this:

In this way, you can push local notifications with Firebase Cloud Messaging (FCM), and trigger messages with cURL REST API in PHP, Node.JS, Python.

No any Comments on this Article


Please Wait...