I am trying to navigate my notifications while terminated, opened. I can navigate when app is open but not on screen. In my home page's initstate method, I created onMessageOpenedApp method to catch notification then call the api. Here is firebase messaging configuration.
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
AppleNotification? apple = message.notification?.apple;
if (notification != null && !kIsWeb) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
),
iOS: const IOSNotificationDetails()),
);
}
}
Future<void> iniciliazarFlutterLocalNotifications() async {
final NotificationAppLaunchDetails? notificationAppLaunchDetails = !kIsWeb &&
Platform.isLinux
? null
: await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
var androidSettings =
const AndroidInitializationSettings('mipmap/launcher_icon');
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
if (!kIsWeb) {
channel = const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title/ description
importance: Importance.high,
ledColor: Colors.blue);
var iOSSettings = const IOSInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false,
);
var initSetttings =
InitializationSettings(android: androidSettings, iOS: iOSSettings);
flutterLocalNotificationsPlugin.initialize(initSetttings);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin>()
?.requestPermissions(
alert: true,
badge: true,
sound: true,
);
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
AppleNotification? apple = message.notification?.apple;
if (notification != null && !kIsWeb) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
),
iOS: const IOSNotificationDetails()),
);
}
});
}
}
And here is my HomeScreen initState variables that only I can navigate my notification then call Api provider.
class Home extends StatefulWidget {
const Home({super.key});
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
void initState() {
super.initState();
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
if (message.data.containsKey('idReferance')) {
Provider.of<CustomerProvider>(context, listen: false)
.getTrackingInformationList(TrackingInformationFilterRequestModel(
searchBox: message.data['idReferance']));
}
});
}
#override
Widget build(BuildContext context) {
return Container();
}
}
There is a function called getInitialMessage which returns the remote notifiction if the app is opened from notification when it is terminated.
if the app is opened from other places it will return null. You can handle the navigation according to this remote notification object. Here is a sample function you can use
Future<void> setupInteractedMessage() async {
// Get any messages which caused the application to open from
// a terminated state.
RemoteMessage? initialMessage =
await FirebaseMessaging.instance.getInitialMessage();
// If the message also contains a data property with a "type" of "chat",
// navigate to a chat screen
if (initialMessage != null) {
_handleMessage(initialMessage);
}
// Also handle any interaction when the app is in the background via a
// Stream listener
FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
}
you can call this method from initstate from your app splash screen or some where you find it relevant. You can see example in this link for more detail
https://firebase.flutter.dev/docs/messaging/notifications/#handling-interaction
Related
i have implemented firebase push notification in my project with payload json,
I have done all the configurations and now when i click on the notification, it works sometimes perfectly but sometimes the redirection just doesn't work, let's say if i click the notification 10 times, it redirects to the desired page for 4 times and rest 6 times, its taking me to home screen. I am sharing my code below.
Main File
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
DartPluginRegistrant.ensureInitialized();
await Firebase.initializeApp();
await SharedPref.initialize();
initilizeCamera();
initializeDb();
FlutterError.onError = (error) {
FirebaseCrashlytics.instance.recordFlutterFatalError(error);
};
PlatformDispatcher.instance.onError = (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
};
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((_) {
runApp(
const ProviderScope(child: MyApp()),
);
});
await pushNotificationToken();
/// Get initial message
await FirebaseMessaging.instance.getInitialMessage();
notificationActions(
action: (RemoteMessage? message) {
if (kDebugMode) {
if (message?.notification != null) {
}
}
if (message != null) {
notificationAction(message: message);
}
},
localNotification: true,
localNotificationAction: (payload) {
if (kDebugMode) {
}
notificationAction(payload: payload);
});
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
systemNavigationBarColor: Colors.white,
statusBarColor: Colors.white,
));
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return KeyboardDismissOnTap(
child: GetMaterialApp(
theme: appThemeData,
debugShowCheckedModeBanner: false,
title: 'XYZ',
// Start the app with the "/" named route. In this case, the app starts
// on the FirstScreen widget.
initialRoute: '/',
initialBinding:XYZBindings(),
routes: {
// When navigating to the "/" route, build the FirstScreen widget.
'/': (context) => const XYZScreen(),
}),
);
}
}
Firebase Notification Code
/// Firebase messaging instance
FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
/// Get firebase notification instance
FirebaseMessaging get firebaseMessagingInstance => _firebaseMessaging;
/// Firebase push notification token
Future<String?> pushNotificationToken() async =>
_firebaseMessaging.getToken().then((value) {
Log.w('FCM TOKEN :: $value');
return value;
});
/// When user clicks on the notification
void notificationActions({
#required Function(RemoteMessage?)? action,
bool localNotification = false,
Function(Map<String, dynamic>)? localNotificationAction,
}) {
/// Make sure localNotification is Not Null
if (localNotification) {
assert(localNotificationAction != null);
}
if (Platform.isIOS) {
_requestPermissions();
}
if (localNotification) {
FlutterLocalNotificationHelper().initializeSettings(
actionCallback: localNotificationAction,
);
}
/// Get initial message
_firebaseMessaging.getInitialMessage().then((RemoteMessage? message) {
action!(message);
});
/// On Message
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
if (localNotification) {
await FlutterLocalNotificationHelper().showNotificationWithDefaultSound(
title: message.notification?.title,
body: message.notification?.body,
payload: jsonEncode(message.data),
);
}
});
/// On Message open app
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
action!(message);
});
}
/// Request permission for iOS
void _requestPermissions() {
_firebaseMessaging.requestPermission(
provisional: true,
);
}
Local Notification Page
/// Helper class for local notifications
class FlutterLocalNotificationHelper {
/// Constructor
factory FlutterLocalNotificationHelper() => _instance;
FlutterLocalNotificationHelper._();
/// Flutter LocalNotification Helper instance
static final FlutterLocalNotificationHelper _instance =
FlutterLocalNotificationHelper._();
/// Flutter LocalNotification for iOS Category
static const String darwinNotificationCategory = 'plainCategory';
/// Notification plugin
late FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin;
/// Flutter LocalNotifications Plugin
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
/// Request local notification
Future<void> requestLocalNotification() async {
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.requestPermission();
}
/// local notification plugin callback
late Function(Map<String, dynamic>) _localNotificationCallback;
/// Initialize local notifications
Future<void> initializeSettings({
#required Function(Map<String, dynamic>)? actionCallback,
}) async {
if (actionCallback != null) {
_localNotificationCallback = actionCallback;
}
/// initialize settings for => Android
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('#mipmap/ic_launcher');
/// initialize settings for => iOS
const DarwinInitializationSettings initializationSettingsIOS =
DarwinInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false,
);
/// Initialize settings for both => Android / iOS
const InitializationSettings initializationSettings =
InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
/// Flutter local notification plugin
_flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
/// Local notification plugin initialize
await _flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (NotificationResponse response) {
if (response.payload != null) {
_localNotificationCallback(json.decode(response.payload!));
}
},
);
/// On notification click
final NotificationAppLaunchDetails? notificationAppLaunchDetails =
await _flutterLocalNotificationsPlugin
.getNotificationAppLaunchDetails();
if (notificationAppLaunchDetails?.didNotificationLaunchApp ?? false) {
await onSelectNotification(
notificationAppLaunchDetails?.notificationResponse.toString(),
);
}
}
/// WHEN USER CLICKS TO NOTIFICATION
Future<void> onSelectNotification(String? payload) async {
if (payload != null) {
final Map<String, dynamic> payloadJson =
jsonDecode(payload) as Map<String, dynamic>;
_localNotificationCallback(payloadJson);
}
}
/// SHOW LOCAL NOTIFICATION
/// 'your channel id', 'your channel name', IS NOT NEEDED
Future<void> showNotificationWithDefaultSound({
#required String? title,
#required String? body,
#required String? payload,
}) async {
/// Android notification details
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(
'your channel id',
'your channel name',
importance: Importance.max,
priority: Priority.high,
color: AppColors.red,
icon: '#mipmap/ic_launcher',
);
/// iOS Notification details
const DarwinNotificationDetails iOSPlatformChannelSpecifics =
DarwinNotificationDetails(
categoryIdentifier: darwinNotificationCategory,
presentSound: true,
presentAlert: true,
badgeNumber: 0,
);
/// Notification platforms details
const NotificationDetails platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics,
iOS: iOSPlatformChannelSpecifics,
);
/// Show notification
await _flutterLocalNotificationsPlugin.show(
0,
title,
body,
platformChannelSpecifics,
payload: payload,
);
}
}
Notifications Action page
void notificationAction(
{RemoteMessage? message, Map<String, dynamic>? payload}) {
The redirection is written here.
}
please let me know that why sometimes the redirection works and sometimes not.
I am using flutter local notification in my application. I could not able to navigate to a specific page by clicking the local notification when the application is in background.
It gives me the error:
_AssertionError ('package:flutter_local_notifications/src/platform_flutter_local_notifications.dart': Failed assertion: line 1018 pos 12: 'callback != null': The backgroundHandler needs to be either a static function or a top
level function to be accessible as a Flutter entry point.)
This is my code:
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
Future<void> listiningToNotification() async {
FirebaseMessaging.onMessageOpenedApp
.listen((message) => notificationOnClick(message));
}
Future<void> localNotification(RemoteMessage message) async {
AndroidNotificationChannel channel = AndroidNotificationChannel(
"local_notification",
message.data["booking_id"],
description: message.data["task_id"],
importance: Importance.max,
playSound: true,
);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings("#drawable/notification_icon");
const InitializationSettings initializationSettings =
InitializationSettings(android: initializationSettingsAndroid);
flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (details) => notificationOnClick(message),
onDidReceiveBackgroundNotificationResponse: (details) =>
firebaseMessagingBackgroundHandler,
);
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,
channelDescription: channel.description,
importance: channel.importance,
playSound: channel.playSound,
color: Colors.white),
),
payload: notification.body);
}
}
#pragma('vm:entry-point')
Future<void> localNotificationBackground(
{required NotificationResponse details}) async {
print(details.payload);
}
What I am doing wrong or what I am missing ?
I also have this function for the firebase background notification. Is this the reason ?
#pragma('vm:entry-point')
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
List<FirebaseApp> app = Firebase.apps;
if (app.length < 2) {
await Firebase.initializeApp(
name: "xxxxxxxxxx", options: DefaultFirebaseOptions.currentPlatform);
}
FirebaseMessaging messaging = FirebaseMessaging.instance;
await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: true,
criticalAlert: false,
provisional: true,
sound: true,
);
}
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
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.
I am trying to navigate to a specific page using local notification, the moment the user touches the notification, below I leave the code of how I am doing it, basically, the problem is when onSelectNotification is called everything that is before is executed but Once Navigator.push is called, it does not go to the screen that I tell it and it does not raise any exceptions and what is after is not executed either.
/// Allows you to navigate to a specific screen from the notification
Future onSelectNotification(String payload) async {
if (payload != null) {
debugPrint('Notification payload: $payload');//it shows
}
await Navigator.push(context, MaterialPageRoute(builder: (context) => AnyScreen()));
debugPrint("go to AnyScreen");//does not show it
}
#override
void initState() {
// TODO: implement initState
super.initState();
/// local notication inicialization
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
'This channel is used for important notifications.', // description
importance: Importance.max,
);
FlutterLocalNotificationsPlugin flip =
new FlutterLocalNotificationsPlugin();
flip
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
const AndroidInitializationSettings android =
AndroidInitializationSettings('app_icon');
final IOSInitializationSettings iOS = IOSInitializationSettings();
final MacOSInitializationSettings macOS = MacOSInitializationSettings();
final InitializationSettings initializationSettings =
InitializationSettings(android: android, iOS: iOS, macOS: macOS);
flip.initialize(initializationSettings,
onSelectNotification: onSelectNotification);
/// listen when the app is open
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
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) {
flip.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id, channel.name, channel.description,
icon: android?.smallIcon,
// other properties...
priority: Priority.high),
));
}
});
}
...