flutter - don't show notification when user is on certain page - flutter

My app has chatting function. And I have implemented Firebase Cloud Messaging and Local Notification.
So when someone sends me a message, notification(one inside android status bar) and local notification(one on the upper part of the screen that holds for like 3 seconds) is shown. They show up when app is opened, on background, and also when app is terminated. (So far so good)
But I don't want both notifications(1. fcm notification, 2. local notification) to show up when I'm already in the chat page with that person. And I have no idea where to start.
Below is my code for handling fcm and show local notification. They are inside main.dart and the main function calls initializeFCM before returning my root page.
Future<void> initializeFCM() async {
await Firebase.initializeApp();
FirebaseMessaging messaging = FirebaseMessaging.instance;
// Firebase Messaging
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
if (settings.authorizationStatus == AuthorizationStatus.authorized) {
// print('User granted permission');
} else
if (settings.authorizationStatus == AuthorizationStatus.provisional) {
// print('User granted provisional permission');
} else {
// print('User declined or has not accepted permission');
}
// Get any messages which caused the application to open from
// a terminated state.
RemoteMessage? initialMessage = await messaging.getInitialMessage();
if (initialMessage != null) {
handleMessage(initialMessage);
}
// initialize local notification
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
// terminated app을 local notification 눌러서 열었을 때 - payload가 정상적으로 동작하지 않음
final NotificationAppLaunchDetails? notificationAppLaunchDetails = await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
final didNotificationLaunchApp = notificationAppLaunchDetails?.didNotificationLaunchApp ?? false;
if (didNotificationLaunchApp) {
onSelectNotification(notificationAppLaunchDetails!.payload);
}
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
showLocalNotification(message);
});
FirebaseMessaging.onBackgroundMessage(showLocalNotification);
FirebaseMessaging.onMessageOpenedApp.listen(handleMessage);
}
void handleMessage(RemoteMessage message) {
if (message.data["screen"] == "message") {
Navigator.push(
navigatorKey.currentContext!,
MaterialPageRoute(
builder: (context) => MessageListPage(),
)
);
}
}
Future<void> onSelectNotification(payload) async {
if(payload != null) {
Map<String, dynamic> data = json.decode(payload);
if (data['screen'] == "message") {
Navigator.push(
navigatorKey.currentContext!,
MaterialPageRoute(
builder: (context) => MessageListPage(),
)
);
}
}
}
Future<void> showLocalNotification(RemoteMessage message) async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
// String screen = message.data['screen'];
// iOS heads up notification setting
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true, // Required to display a heads up notification
badge: true,
sound: true,
);
// android channel setting
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
importance: Importance.max,
);
// initialize local notification
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
await flutterLocalNotificationsPlugin.initialize(InitializationSettings(
android: AndroidInitializationSettings('#drawable/mentea_ic_stat_name'),
iOS: IOSInitializationSettings()),
onSelectNotification: onSelectNotification);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
// If `onMessage` is triggered with a notification, construct our own
// local notification to show to users using the created channel.
if (notification != null && android != null) {
// print('Message also contained a notification: ${message.notification}');
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
'high_importance_channel', //channel.id,
'High Importance Notifications', //channel.name,
icon: android.smallIcon,
color: primaryColor,
// other properties...
),
),
payload: json.encode(message.data)
);
}
}

I don't know if you still have this problem, but I'll post my solution here.
It happens that when we send a push notification with the notification message feature, the FCM plugin automatically sends a notification on the device if the App is in background and finished, where we can only customize the foreground notification through Local Notifications or other solutions within of the App. So the solution pointed out in the Firebase documentation for this situation is to send the push notification only as a data message, without including the notification object. Below I show the examples and the documentation link.
Documentation: https://firebase.google.com/docs/cloud-messaging/concept-options?authuser=1&hl=pt#notifications_and_data_messages
Combined notification example:
const payload = {
notification: {
title: '$FooCorp up 1.43% on the day',
body: '$FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.'
},
data: {
stock: 'GOOG',
open: '829.62',
close: '635.67'
}
};
Notification example with data message only:
const payload = {
data: {
score: '850',
time: '2:45'
}
};
Notification example with notification message only:
const payload = {
notification: {
title: '$FooCorp up 1.43% on the day',
body: '$FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.'
}
};
So, so that you can customize all forms of notification (foreground, background and terminated), send a push notification through your backend as a data message only.

Related

How to push open a page from a notification flutter

I have my method that loads firebase cloud messaging and listens for incoming messages as follows.
void loadFCM() async {
if (!kIsWeb) {
channel = const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
importance: Importance.high,
enableVibration: true,
);
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
/// Create an Android Notification Channel.
///
/// We use this channel in the `AndroidManifest.xml` file to override the
/// default FCM channel to enable heads up notifications.
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
/// Update the iOS foreground notification presentation options to allow
/// heads up notifications.
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
}
}
void listenFCM() async {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
if (notification != null && android != null && !kIsWeb) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
icon: 'launch_background',
),
),
);
if (message.data['screen'] == 'chat') {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ChatScreen(
uid: message.data['uid'],
),
),
);
}
}
});
}
As seen I'm storing the screen I want in the data of the screen I want when I send the message and have code in the listenFCM function to attempt to change the screen but it wont work, I receive the notification but dont change screen. I'm currently using this method to send a message to a specific user
void sendPushMessage(String token, String body, String title) async {
try {
await http.post(
Uri.parse('https://fcm.googleapis.com/fcm/send'),
headers: <String, String>{
'Content-Type': 'application/json',
'Authorization': 'key=${api}',
},
body: jsonEncode(
<String, dynamic>{
'notification': <String, dynamic>{'body': body, 'title': title},
'priority': 'high',
'data': <String, dynamic>{
'click_action': 'FLUTTER_NOTIFICATION_CLICK',
'id': '1',
'status': 'done'
'screen': 'chat'
},
"to": token,
},
),
);
} catch (e) {
print("error push notification");
}
}
Im trying to modify it so I can send a push notification they open a chat page. it would be a chat(userid) sort of thing but I dont want to send the chatId in the body of the notification or anything so how can I have my app push open my chat page when tapped from app close/open etc, Thanks for reading!

iOS firebase getInitialMessage not working Flutter

I installed firebase notification package in my Flutter project and setup the necessary settings for sending data.
Everything works fine on android, when the app is completely closed, when I send a parameter via firebase, the page I want opens, but on the ios part, when I click on the notification, it does not catch the click and the page I want does not open.
I would be very happy if you could help me where is the main point I should pay attention to for the ios part.
Main.dart
initialMessage = await FirebaseMessaging.instance.getInitialMessage();
if (initialMessage != null) {
if (initialMessage!.data['type'] == 'notification') {
await Future.delayed(const Duration(seconds: 4));
navigatorKey.currentState?.pushNamed(
'/notification'); // navigate to login, with null-aware check
}
}
pushNotificationService.dart
class PushNotificationService {
Future<void> setupInteractedMessage() async {
await Firebase.initializeApp();
RemoteMessage? initialMessage =
await FirebaseMessaging.instance.getInitialMessage();
if (initialMessage != null &&
initialMessage.data['type'] == 'notification') {
await Future.delayed(const Duration(seconds: 6));
navigatorKey.currentState?.pushNamed(
'/notification'); // navigate to login, with null-aware check
}
// Also handle any interaction when the app is in the background via a
// Stream listener
// This function is called when the app is in the background and user clicks on the notification
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
// Get.toNamed(NOTIFICATIOINS_ROUTE);
print(message.toMap().toString());
print(message.data['type'].toString());
if (message.data['type'] == 'notification') {
navigatorKey.currentState?.pushNamed('/notification');
}
});
await enableIOSNotifications();
await registerNotificationListeners();
}
registerNotificationListeners() async {
AndroidNotificationChannel channel = androidNotificationChannel();
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
var androidSettings =
const AndroidInitializationSettings('#mipmap/ic_launcher');
var iOSSettings = const IOSInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false,
);
var initSetttings =
InitializationSettings(android: androidSettings, iOS: iOSSettings);
flutterLocalNotificationsPlugin.initialize(initSetttings,
onSelectNotification: (message) async {
// This function handles the click in the notification when the app is in foreground
// Get.toNamed(NOTIFICATIOINS_ROUTE);
});
// onMessage is called when the app is in foreground and a notification is received
FirebaseMessaging.onMessage.listen((RemoteMessage? message) {
// Get.find<HomeController>().getNotificationsNumber();
print(message!.data['type'].toString());
print(message.toMap().toString());
if (message.data['type'] == 'notification') {
navigatorKey.currentState?.pushNamed('/notification');
}
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
// If `onMessage` is triggered with a notification, construct our own
// local notification to show to users using the created channel.
if (notification != null && android != null) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
icon: android.smallIcon,
playSound: true,
),
),
);
}
});
}
enableIOSNotifications() async {
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true, // Required to display a heads up notification
badge: true,
sound: true,
);
}
androidNotificationChannel() => const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
importance: Importance.max,
);
}
info.plist background modules
UIBackgroundModes
fetch
processing
remote-notification

Navigate to another screen when I click on Firebase push notification either in foreground or background in Flutter

I use Firebase messaging in my Flutter app , I want to navigate to another screen when I click on the notification even my app is in foreground or background , I used many functions and it doesn't trigger the click event and I can't find anything can solve my problem .
When I click on the notification when app is in foreground or background , nothing happened because it navigate to the same page .
And when I click on the notification when app is terminated , it opens on Splash screen and go to the home not the screen that I want .
I added this intent-filter in my Manifest
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
And I added this to the Json object
"click_action": "FLUTTER_NOTIFICATION_CLICK",
And here is how can I get background FCM in the main.dart
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance', // id
'High Importance Notifications', // title
importance: Importance.high,
playSound: true);
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
SessionManager sessionManager = SessionManager();
await Firebase.initializeApp();
//final sound = 'sound.mp3';
print('A bg message just showed up : ${message.messageId}');
final android = AndroidInitializationSettings('#mipmap/ic_launcher');
final ios = IOSInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false,);
final settings = InitializationSettings(android: android,iOS: ios);
flutterLocalNotificationsPlugin.initialize(settings,);
if(message.data['title'].toString().toLowerCase()=="new request") {
sessionManager.getBadge().then((badge) {
if (badge != null) {
int x = badge + 1;
sessionManager.saveBadge(x);
print("notification number is " + x.toString());
}
else {
sessionManager.saveBadge(1);
}
});
}
flutterLocalNotificationsPlugin.show(
message.data.hashCode,
message.data['title'],
message.data['body'],
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
importance: Importance.high,
priority: Priority.high,
// sound: RawResourceAndroidNotificationSound(sound.split('.').first),
playSound: true,
icon: '#mipmap/ic_launcher',
),
));
/*NotificationApi.showNotification(
title: message.data['title'],
body: message.data['body'],
payload: "",
id: int.parse(channel.id));*/
}
Future<void> main() async{
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
runApp(MyApps());
// configLoading();
}
class MyApps extends StatefulWidget {
const MyApps({Key? key}) : super(key: key);
#override
State<StatefulWidget> createState() {
return MyApp();
}
}
class MyApp extends State<MyApps> {
static ValueNotifier<int> strikeNotifier = ValueNotifier(0);
Color _primaryColor = Color(0xff0d8b75);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return ScreenUtilInit(
builder: () => MaterialApp(
debugShowCheckedModeBanner: false,
home: SplashScreen(),
),
designSize: const Size(1080, 2280),
);
}
void showNotification(String title, String body) async {
await _demoNotification(title, body);
}
Future<void> _demoNotification(String title, String body) async {
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'channel_I', 'channel name',
showProgress: true,
priority: Priority.high,
playSound: true,
ticker: 'test ticker');
var iOSChannelSpecifics = IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics, iOS: iOSChannelSpecifics);
await flutterLocalNotificationsPlugin
.show(0, title, body, platformChannelSpecifics, payload: 'test');
}
#override
void initState() {
super.initState();
FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) {
if (message != null) {
Navigator.push(context, MaterialPageRoute(builder: (context)=>DoneAndPaiedPagess(0)));
}
});
getToken().then((value) {
if(value!=null) {
AppConstants.firebaseToken = value;
}
});
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
new FlutterLocalNotificationsPlugin();
var initializationSettingsAndroid = AndroidInitializationSettings('#mipmap/ic_launcher');
var initializationSettingsIOS = IOSInitializationSettings();
var initializationSettings = InitializationSettings(android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
flutterLocalNotificationsPlugin.initialize(initializationSettings,
);
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
var data = message.data;
// AndroidNotification? android = message.notification?.android;/
if (data != null ) {
if(data['title'].toString().toLowerCase()=="new request") {
SessionManager sessionManager = SessionManager(context);
sessionManager.getBadge().then((badge) {
if (badge != null) {
setState(() {
int x = badge + 1;
strikeNotifier.value = x;
sessionManager.saveBadge(x);
});
}
else {
strikeNotifier.value = 1;
sessionManager.saveBadge(1);
}
});
}
print("entered");
flutterLocalNotificationsPlugin.show(
data.hashCode,
data['title'],
data['body'],
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
playSound: true,
icon: '#mipmap/ic_launcher',
),
));
}
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
Navigator.push(context, MaterialPageRoute(builder: (context)=>DoneAndPaiedPagess(0)));
});
}
Future<String?> getToken() async{
String? token = await FirebaseMessaging.instance.getToken();
print("token is "+token!);
return token;
}
}
In yaml
firebase_core: ^1.12.0
firebase_messaging: ^11.2.6
dependency_overrides:
firebase_messaging_platform_interface: 3.1.6
Edit : from multiple solutions , I tried the most common solution that I used onMessageOpenedApp in initState but it doesn't enter in it
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
Navigator.push(context, MaterialPageRoute(builder: (context)=>DoneAndPaiedPagess(0)));
});
In your code, you are using the flutter_local_notifications plugin and you are creating local notification when you get a push notification from firebase messaging.
Since the notification is not created by firebase messaging so, you are not getting on tap callback in getInitialMessage and onMessageOpenedApp.
In order to get on tap callback on local notifications, you can pass a callback function while initializing flutter_local_notifications
flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: onSelectNotification);
void selectNotification(String payload) async {
if (payload != null) {
debugPrint('notification payload: $payload');
// Here you can check notification payload and redirect user to the respective screen
await Navigator.push(
context,
MaterialPageRoute<void>(builder: (context) => SecondScreen(payload)),
);
}
}
For more, you can check flutter_local_notifications documentation
On your home widget within initState, check the getInitialMessage value :
// get the remote message when your app opened from push notification while in background state
RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage();
// check if it is exists
if (initialMessage != null) {
// check the data property within RemoteMessage and do navigate based on it
}
Check the firebase flutter documentation here https://firebase.flutter.dev/docs/messaging/notifications/#handling-interaction.
Use onMessageOpenedApp stream to listen when a notification is opened in the foreground or background. When the application is terminated, use getInitialMessage to get a pending notification.

Flutter - Endless notification on a single pusher beams event

Describe the bug
I am using pusher beams to fire event from server and I use flutter local notification to show the notification when the event is received by app.
Sample code to reproduce the problem
I have called initPusherBeams() in my init state (please read to the end I am quite sure this issues is with flutter local notifications)
#override
void initState() {
super.initState();
_setAuthData().then((_) {
if (_user?.id != null) initPusherBeams();
});
// notification related
_notiInit();
_requestPermissions();
_configureDidReceiveLocalNotificationSubject();
_configureSelectNotificationSubject();
// ask for app rating
WidgetsBinding.instance.addPostFrameCallback((_) => _ratingDialog());
}
and then, ininitPusherBeams function, I have
initPusherBeams() async {
// Let's see our current interests
await PusherBeams.instance.setDeviceInterests([
// 'App.Models.User.${_user!.id}',
'debug-new'
]);
// This is not intented to use in web
if (!kIsWeb) {
await PusherBeams.instance.onMessageReceivedInTheForeground(_onMessageReceivedInTheForeground);
}
}
void _onMessageReceivedInTheForeground(Map<Object?, Object?> data) {
AndroidNotificationDetails androidPlatformChannelSpecifics = const AndroidNotificationDetails(
'channel',
'My App Name',
channelDescription: 'New user registered',
playSound: false,
styleInformation: DefaultStyleInformation(true, true),
);
const IOSNotificationDetails iOSPlatformChannelSpecifics = IOSNotificationDetails(presentSound: false);
NotificationDetails platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics,
iOS: iOSPlatformChannelSpecifics,
);
log(json.encode(data));
// flutterLocalNotificationsPlugin.show(
// 0,
// 'New user registered',
// data['body'].toString(),
// platformChannelSpecifics,
// payload: data['title'].toString(),
// );
}
If I comment out flutterLocalNotificationsPlugin.show, the event fire only once as you can see in below screenshot.
but if I uncomment showing notification part which is the following code
flutterLocalNotificationsPlugin.show(
0,
'New user registered',
data['body'].toString(),
platformChannelSpecifics,
payload: data['title'].toString(),
);
The event fire endlessly (like in the screenshot below) and the notification keep appearing for each event continuously.
How come showing notification became some kind of loop and how should I fix this. Thanks in advance.
I end up showing the notification with SnackBar while the app is in foreground. While the apps is in background, the pusher beams package handle the notification and send it to notification center. Here's my code
initPusherBeams() async {
// Let's see our current interests
await PusherBeams.instance.setDeviceInterests([
'App.Models.User.${_user!.id}',
'debug-new'
]);
// This is not intented to use in web
if (!kIsWeb) {
await PusherBeams.instance.onMessageReceivedInTheForeground(_onMessageReceivedInTheForeground);
}
}
void _onMessageReceivedInTheForeground(Map<Object?, Object?> data) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(correctFont(data['body'] as String)),
duration: const Duration(milliseconds: 3000),
backgroundColor: brandBrown,
),
);
}```

FirebaseMessaging.instance.getInitialMessage() is not called in terminated state

FirebaseMessaging.instance.getInitialMessage() is not called in terminated state when we click notification that contains message data like this ,instead it is displaying screen from splash screen
{
"registration_ids": [
""
],
"data": {
"title": "Flutter9 Object Notification.3...",
"body": "this is flutter Data Object notification test message from",
"android_channel_id": "dgdgsdfgs",
},
"android":{
"priority":"high"
}
}
Given that you not displayed how you setup your fcm , here is how to go about it
/// Create a [AndroidNotificationChannel] for heads up notifications
late AndroidNotificationChannel channel;
/// Initialize the [FlutterLocalNotificationsPlugin] package.
late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
/// To verify things are working, check out the native platform logs.
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// If you're going to use other Firebase services in the background, such as Firestore,
// make sure you call `initializeApp` before using other Firebase services.
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
print('Handling a background message ${message.messageId}');
}
in main.dart
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
// setup displaying notifications
channel = const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title// description
importance: Importance.high,
);
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
/// Create an Android Notification Channel.
///
/// We use this channel in the `AndroidManifest.xml` file to override the
/// default FCM channel to enable heads up notifications.
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
/// Update the iOS foreground notification presentation options to allow
/// heads up notifications.
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
handle message call this in your initstate
FirebaseMessaging.instance
.getInitialMessage()
.then((RemoteMessage? message) {
if (message != null) {
// do message things
}
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
showMessage(message: message);
});
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
if (notification != null && android != null) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
),
iOS: IOSNotificationDetails(subtitle: notification.title)));
}
});
incase you need to navigate on receiving a message
void showMessage({required RemoteMessage message}) async {
if (message.data['route'] == "mypage") {
var myparams = message.data['payload'];
Navigator.of(context).push(MaterialPageRoute(
fullscreenDialog: true,
builder: (_) {
return MyPage(
params:myparams,
);
})); ...
With FCM, you can send two types of messages to clients:
Notification messages, are sometimes thought of as "display messages." These are handled by the FCM SDK automatically.
Data messages, which are handled by the client app. "
https://firebase.google.com/docs/cloud-messaging/concept-options
What you are trying to send is a data message, my best guess is that the firebase SDK does not recognize the data message so it does not trigger the firebase message event listener. Your notification must have a 'notification' field for firebase SDK to listen to.