Flutter Notification Using Firebase Cloud Messaging and Local Notification plugin

Amit Kumar
4 min readApr 23, 2021

--

A guide for how to send fcm messages programmatically to different devices in flutter. Before reading you must compelete firebase setup for flutter.

plugins required:

Install plugins:

add in pubsecyaml dependencies:

firebase_messaging: ^9.1.2
http: ^0.13.1

import files:

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:http/http.dart';

Add in app level build to gradle:

// in dependencies section
implementation ‘com.google.firebase:firebase-messaging’
//change minSdk version
minSdkVersion 21

Add in Androidmanifest.xml file

// add inside application tag
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>

Step 1: Setup Firebase project for App:

Hoping you have done firebase setup already..

Step 2: firebase cloud messaging service:

Make a class to access various fcm functions ..

firebase_messaging | Flutter Package (pub.dev)

// make a singleton class where everything will be instantiated
class FireBaseNotificationService {
LocalNotificationManagerFlutter.getInstance();
static FirebaseMessaging fcm = FirebaseMessaging.instance;
// fcmserviceApi will be discussed laterstatic FcmServiceApi fcmApi = FcmServiceApi();//Returns a Stream that is called when an incoming FCM payload is //received whilst the Flutter instance is in the foreground.
//The Stream contains the [RemoteMessage].
onMessage() {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
RemoteNotification notification = message.notification;
AndroidNotification android = message.notification?.android;
// on recieving fcm message launch a notification notification
// use recieved data to make a required notification
if(notification!=null&& android!=null){
// implement local notification

const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
'This channel is used for important notifications.',
importance: Importance.high,
);
await flutterLocalNotificationsPlugin.show(
0, 'plain title', 'plain body',
AndroidNotificationDetails(
channel.id,
channel.name,
channel.description,
icon: 'launch_background',
importance: Importance.max,
priority: Priority.high,
payload: 'item x');
}
}
});
}
//A Stream event will be sent if the app has opened from a //background state (not terminated).onMessageOpenedApp() async {
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
// do task
});
}
//If the application has been opened from a terminated state via a //[RemoteMessage] (containing a [Notification]), it will be //returned, otherwise it will be null.onIntialMessage() async {
fcm.getInitialMessage().then((RemoteMessage message) {
// do task
});
}
//Returns the default FCM token for this device and optionally a [senderId], used for individual msg.
Future<String> token() async {
return await fcm.getToken();
}
//Subscribe to topic in background,[topic] must match the following //regular expression: [a-zA-Z0-9-_.~%], used for grouped notificationFuture<bool> subscribeTopic(String topic) async {
try {
await fcm.subscribeToTopic(topic);
return true;
} catch (e) {
print(e);
return false;
}
}
Future<String> unSubscribeTopic(String topic) async {
try {
await fcm.unsubscribeFromTopic(topic);
return 'sucessfully Unsubscribed $topic';
} catch (e) {
print(e);
return 'something went wrong during subscribing';
}}
// function to send fcm messageFuture sendCustomMessage(Map<String, dynamic> data) async {
await fcmApi.sendMessage(data);
}}

Set a message handler function which is called when the app is in the background or terminated.

Note: This provided handler must be a top-level function and cannot be anonymous otherwise an [ArgumentError] will be thrown.

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// do task
}
void main(){WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// Set the background messaging handler early on, as a named top-level functionFirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
}

class to send message to fcm server using http request

class FcmServiceApi {
// url to send messga to fcm server
static final fcmUrl = 'https://fcm.googleapis.com/fcm/send';Future sendMessage(Map data) async {
try {
// further we discuss format of data valid to send in this request
final msg = jsonEncode(data);
Map<String, String> headers = {
'content-type': 'application/json',
'Authorization':
'key= fill your server key'
};
http.Response response =
await http.post(Uri.parse(fcmUrl), headers: headers, body: msg);
} catch (e) {
print(e);
}}
}
you can get server key in project setting of firebase

Message data sending to fcm server:

“to” key refers to whom we want to send fcm messages. here i am sending msg to all devices subscribed to specific topic name animal. To send specific message use fcm token in “to” key.

This data I have shown you used to send notification to cross platform devices but there are also platform specific things you can send .

About FCM messages | Firebase (google.com)

final data = {
"to": "/topics/animal",
"notification": {
"body": "Body of Your Notification",
"title": "Title of Your Notification" },
"data": {
"body": "Body of Your Notification in Data",
"title": "Title of Your Notification in Title",
"key_1": "Value for key_1",
"key_2": "Value for key_2"
}};
// to send msg via fcm token add server key in "to"
"to": "server key"

Step 3: local notification plugin:

here you will get all setup needed for local notification plugin.

Local Push Notification in Flutter | by Anmol Gupta | FlutterDevs | Medium

🌸 Thank you for reading 🌸

--

--

Responses (1)