So this is my code did made any mistake? I'm getting notifications but not redirecting to specified page.
tried many ways but its not even going inside function handleNavigation in foreground and in background its call but again landing on homepage.
I know whats the mistake I'm doing.
here is the code for reference.
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:./main.dart';
import 'package:../../../connectionscreen.dart';
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
log("Handling a background message: ${message.messageId}");
log("Handling a background message: ${message.notification?.title}");
log("Handling a background message: ${message.notification?.body}");
log("Handling a background message: ${message.data}");
}
class FirebaseCM {
static FirebaseMessaging messaging = FirebaseMessaging.instance;
static void permissionRequest() async {
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
debugPrint('User granted permission: ${settings.authorizationStatus}');
final fcmToken = await messaging.getToken();
log('Token: $fcmToken');
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
initPushNotification();
initLocalNotifications();
}
static void handleNavigation(RemoteMessage? message) {
log("--->message:$message");
if (message == null) return;
navigatorKey.currentState
?.pushNamed(ConnectionScreen.route, arguments: message);
}
static Future<void> initPushNotification() async {
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
FirebaseMessaging.instance.getInitialMessage().then(handleNavigation);
FirebaseMessaging.onMessageOpenedApp.listen(handleNavigation);
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
messageHandling();
}
static void messageHandling() async {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
final notification = message.notification;
log('Got a message whilst in the foreground!');
log('Message data: ${message.data}');
if (notification != null) {
_flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
androidChannel.id,
androidChannel.name,
channelDescription: androidChannel.description,
icon: '@mipmap/ic_launcher',
),
),
payload: jsonEncode(message.toMap()),
);
log('Message also contained a notification: ${message.notification}');
}
});
}
static const androidChannel = AndroidNotificationChannel(
'high_importance_channel',
'High Importance Notifications',
description: 'This channel is used for important notifications.',
importance: Importance.high,
);
static final FlutterLocalNotificationsPlugin
_flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
static Future<void> initLocalNotifications() async {
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
const DarwinInitializationSettings initializationSettingsDarwin =
DarwinInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
);
const InitializationSettings initializationSettings =
InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsDarwin,
);
_flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (payload) async {
log("2.$payload at ${DateTime.now()}");
handleNavigation;
},
onDidReceiveBackgroundNotificationResponse: (payload) async {
log("2.$payload");
final messageData = jsonDecode(payload.toString());
handleNavigation(RemoteMessage.fromMap(messageData));
},
);
final platform =
_flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>();
await platform?.createNotificationChannel(androidChannel);
}
}
Avoid using static as it will throw the warnings. I made few mistakes and not properly accessed the payload that caused issues. I made relevant changes so that code works as expected.
beginner who want to add FCM can just use this code.
In main.dart
final navigatorKey = GlobalKey<NavigatorState>();
void main() {
FirebaseCM().initNotifications();
....
}
add these in MaterialApp
return MaterialApp(
navigatorKey: navigatorKey,
routes: {
YourPage.route: (context) => const YourPage(),}
home: const Homepage(),
...
FCM logic
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:main.dart';
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
log("Handling a background message: ${message.messageId}");
log("Handling a background message: ${message.notification?.title}");
log("Handling a background message: ${message.notification?.body}");
log("Handling a background message: ${message.data}");
}
class FirebaseCM {
static FirebaseMessaging messaging = FirebaseMessaging.instance;
Future<void> initNotifications() async {
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
debugPrint('User granted permission: ${settings.authorizationStatus}');
final fcmToken = await messaging.getToken();
log('Token: $fcmToken');
initPushNotification();
initLocalNotifications();
}
void handleNavigation(RemoteMessage? message) {
log("--->message:$message");
if (message == null) return;
log(navigatorKey.currentState.toString());
navigatorKey.currentState
?.pushNamed(YourPage.route, arguments: message); --> add your page that you want to navigate.
}
Future initPushNotification() async {
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
FirebaseMessaging.instance.getInitialMessage().then(handleNavigation);
FirebaseMessaging.onMessageOpenedApp.listen(handleNavigation);
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
FirebaseMessaging.onMessage.listen((message) {
final notification = message.notification;
if (notification == null) return;
_flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
androidChannel.id,
androidChannel.name,
channelDescription: androidChannel.description,
icon: '@mipmap/ic_launcher',
),
),
payload: jsonEncode(message.toMap()),
);
});
}
final androidChannel = const AndroidNotificationChannel(
'high_importance_channel',
'High Importance Notifications',
description: 'This channel is used for important notifications.',
importance: Importance.high,
);
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
Future initLocalNotifications() async {
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
const DarwinInitializationSettings initializationSettingsDarwin =
DarwinInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
);
const InitializationSettings settings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsDarwin,
);
_flutterLocalNotificationsPlugin.initialize(
settings,
onDidReceiveNotificationResponse: (payload) async {
final message = RemoteMessage.fromMap(jsonDecode(payload.payload!));
handleNavigation(message);
},
);
final platform =
_flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>();
await platform?.createNotificationChannel(androidChannel);
}
}