Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When launch app from notification tap(when app is terminated):- it is not navigating to specific screen || get initial message not working #16871

Open
1 task done
DeepakYiron opened this issue Dec 13, 2024 · 5 comments
Labels
blocked: customer-response Waiting for customer response, e.g. more information was requested. platform: android Issues / PRs which are specifically for Android. plugin: messaging type: bug Something isn't working

Comments

@DeepakYiron
Copy link

DeepakYiron commented Dec 13, 2024

Is there an existing issue for this?

  • I have searched the existing issues.

Which plugins are affected?

No response

Which platforms are affected?

No response

Description

Here is my payload

{
"message": {
"token": "my device token",
"data": {
"title": "Custom Notification",
"body": "This is a custom notification with actions.",
"click_action": "FLUTTER_NOTIFICATION_CLICK"
},
"android": {
"priority": "high"
}
}
}

I JUST WANT TO USE CUSTON NOTIFICATION (NOT DEFAULT ONE)
NOTE:- in default notification everything is working fine nut what if i need to use my own custom notification with action etc

when i change payload from this to give below its working fine when app in launched from notification when app is terminated

i am getting issue only when app is terminated and launched from notification tap

{
"message": {
"token": "my device token",
"notification": {
"title": "Custom Notification",
"body": "This is a custom notification with actions.",
},
"android": {
"priority": "high"
}
}
}

i am using data:{} instead of notification:{} because notification trigger default push notification:- i am using my custom notification and working fine when app is foreground and background but not in case when app is terminated and launched from notification tap

please suggest:-
FirebaseMessaging messaging = FirebaseMessaging.instance;
RemoteMessage? initialMessage = await messaging.getInitialMessage();

this method is not working when i used data:{} in payload

Reproducing the issue

import 'dart:async';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import "package:flutter/material.dart";
import 'package:flutter/services.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get/get.dart';
import 'package:notification_permissions/notification_permissions.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:t_three_crm/constants/constants.dart';
import 'package:t_three_crm/push_notification/notification_service.dart';
import 'package:t_three_crm/resources/font_family.dart';
import 'package:t_three_crm/screens/login/view/LoginScreen.dart';
import 'package:t_three_crm/screens/login/view/reset_password_screen.dart';
import 'dart:io';
import 'package:t_three_crm/screens/main_dashboard/view/main_dashboard.dart';

@pragma('vm:entry-point')
Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
NotificationService().showLocalNotification(
message.data['title']??"",
message.data['body']??"",
"",
);
}

const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
importance: Importance.high,
);

Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
//initialize background
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
HttpOverrides.global = MyHttpOverrides();
NotificationService().init();
String initialRoute = await determineInitialRoute();

SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]).then((_) {
runApp(MyApp(initialRoute: initialRoute,));
});
}

Future determineInitialRoute() async {
FirebaseMessaging messaging = FirebaseMessaging.instance;
RemoteMessage? initialMessage = await messaging.getInitialMessage();
if (initialMessage != null) {
return "Profile";
}

return '';
}

class MyApp extends StatefulWidget {
MyApp({Key? key, required this.initialRoute}) : super(key: key);
final String initialRoute;
@OverRide
State createState() => _MyAppState();
}

class _MyAppState extends State {

late String token;
getToken() async {
token = (await FirebaseMessaging.instance.getToken())!;
Constants.fcmToken=token;
print(token);
}

var isBKNotification=false;
@OverRide
void initState() {
super.initState();
getToken();

}
@OverRide
Widget build(BuildContext context) {
return GetMaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
fontFamily: AppFontFamily.gothic,
useMaterial3: false,
appBarTheme: AppBarTheme(
surfaceTintColor: Colors.transparent,
systemOverlayStyle: SystemUiOverlayStyle(
statusBarColor: Colors.transparent
)
),
datePickerTheme: DatePickerThemeData(
headerForegroundColor: Colors.white,
backgroundColor: Colors.white,
headerBackgroundColor: Colors.blue,
dividerColor: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0), // this is the border radius of the picker
),
),
scaffoldBackgroundColor: Colors.white,
// colorScheme: ColorScheme.fromSeed(onPrimary: Colors.white, seedColor: Colors.white)
),
//for notification tap navigate
home:widget.initialRoute=="Profile"?ProfileScreen(): Splash(),

);

}
}

import 'dart:convert';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get/get.dart';
import 'package:t_three_crm/screens/home/view/dashboard.dart';

class NotificationService {
final _messaging = FirebaseMessaging.instance;
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();

Future init() async {
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.requestNotificationsPermission();

const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings(
  '@drawable/ic_launcher',
);

final DarwinInitializationSettings initializationSettingsIOS =
DarwinInitializationSettings(
  onDidReceiveLocalNotification:
      (int id, String? title, String? body, String? payload) async {
    onSelectNotificationResponse;
  },
);

var initializationSettings = InitializationSettings(
  android: initializationSettingsAndroid,
  iOS: initializationSettingsIOS,
);

await flutterLocalNotificationsPlugin.initialize(
  initializationSettings,
  onDidReceiveNotificationResponse: (payload) {
    onSelectNotificationResponse(payload);
  },

);

FirebaseMessaging.onMessage.listen(
      (RemoteMessage event) {
    print('called:-');
    showLocalNotification(
      event.notification?.title??"",
      event.notification?.body??"",
      json.encode(event.data).toString(),
    );

    // showLocalNotification(
    //   event.data['title']??"",
    //   event.data['body']??"",
    //   "",
    // );
        },
);

FirebaseMessaging.onMessageOpenedApp.listen(
      (message) async {
    print('---- onMessageOpenedApp called ----');
    /// this will work when payload is notification:{titile:"scjsb",body:"sjcjsbcj"}
    ///Navigate to screen when app is in background :- On notification tap this will navigate to account screen when app is in background
    await Get.to(DashBoard(index: 0));
        },
);
await FirebaseMessaging.instance
    .setForegroundNotificationPresentationOptions(
  alert: true,
  badge: true,
  sound: true,
);

}
Future onSelectNotificationResponse(
NotificationResponse notificationResponse) async {
final String? payload = notificationResponse.payload;
if (payload != null) {
await Get.to(DashBoard(index: 0));
/// this will execute and navigate to screen when tap on notification when app is in foreground and even in background and payload for this is
/// this will work in both scenario (BACKGROUND & FOREGROUND)

    ///     {
    ///       "message": {
    ///   "token": "fZ7DJn-_RQ6BhDBAyQimdo:APA91bE9FWBtIxkDL5THBnFRGc7AXqb-Otg3z9kmVV9Mhrf8h9r1QV1qLEExRFIz_WiB2HcEu1jwchBUOcgVOHerDFJri1pnQ9J-kgxif3gU8qfVHggkJj8",
    ///  "notification": {
    ///   "title": null,
    ///   "body": null
    /// },
    ///   "data": {
    ///   "title": "Test notification using Auth 99999CSCSC",
    ///   "body": "Notification with new urlSCSCSCSC"
    /// },
    ///   "android": {
    ///   "priority": "high"
    /// }
    /// }
    /// }


}

}

void showLocalNotification(String? title, String? message, [String? payload]) async {
AndroidNotificationDetails androidPlatformChannelSpecifics = AndroidNotificationDetails(
title ?? '',
message ?? '',
importance: Importance.max,
priority: Priority.high,
enableVibration: true, // Enable vibration
playSound: true,
showWhen: false,
icon: "@drawable/ic_launcher"
);
DarwinNotificationDetails iosPlatformChannelSpecifics =
DarwinNotificationDetails(presentBadge: true, presentSound: true, presentAlert: true,);
NotificationDetails platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics,
iOS: iosPlatformChannelSpecifics,
);
await flutterLocalNotificationsPlugin.show(
0,
title,
message,
platformChannelSpecifics,
payload: payload,
);
}
}

Firebase Core version

3.1.0

Flutter Version

3.22.2

Relevant Log Output

No response

Flutter dependencies

Expand Flutter dependencies snippet
Replace this line with the contents of your `flutter pub deps -- --style=compact`.

Additional context and comments

No response

@DeepakYiron DeepakYiron added Needs Attention This issue needs maintainer attention. type: bug Something isn't working labels Dec 13, 2024
@DeepakYiron DeepakYiron changed the title When launch app from notification tap:- it is not navigating to specific screen || get initial message not working When launch app from notification tap:- it is not navigating to specific screen || get initial message not working when my payload is like this:- { "message": { "token": "my device token", "data": { "title": "Custom Notification", "body": "This is a custom notification with actions.", "click_action": "FLUTTER_NOTIFICATION_CLICK" }, "android": { "priority": "high" } } } Dec 13, 2024
@DeepakYiron DeepakYiron changed the title When launch app from notification tap:- it is not navigating to specific screen || get initial message not working when my payload is like this:- { "message": { "token": "my device token", "data": { "title": "Custom Notification", "body": "This is a custom notification with actions.", "click_action": "FLUTTER_NOTIFICATION_CLICK" }, "android": { "priority": "high" } } } When launch app from notification tap:- it is not navigating to specific screen || get initial message not working Dec 13, 2024
@SelaseKay SelaseKay added plugin: messaging platform: android Issues / PRs which are specifically for Android. labels Dec 13, 2024
@SelaseKay
Copy link
Contributor

@DeepakYiron, could you please provide a minimal code sample that uses only FlutterFire plugins? This will help us isolate the issue effectively. Additionally, ensure the code is properly formatted for clarity. Thank you!

@SelaseKay SelaseKay added blocked: customer-response Waiting for customer response, e.g. more information was requested. and removed Needs Attention This issue needs maintainer attention. labels Dec 13, 2024
@DeepakYiron
Copy link
Author

------main.dart-----

@pragma('vm:entry-point')
Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
NotificationService().showLocalNotification(
message.data['title']??"",
message.data['body']??"",
"",
);
}

const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
importance: Importance.high,
);

Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
//initialize background
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
HttpOverrides.global = MyHttpOverrides();
NotificationService().init();
String initialRoute = await determineInitialRoute();

SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]).then((_) {
runApp(MyApp(initialRoute: initialRoute,));
});
}

Future determineInitialRoute() async {
FirebaseMessaging messaging = FirebaseMessaging.instance;
RemoteMessage? initialMessage = await messaging.getInitialMessage();
if (initialMessage != null) {
return "Profile";
}

return '';
}

class MyApp extends StatefulWidget {
MyApp({Key? key, required this.initialRoute}) : super(key: key);
final String initialRoute;
@OverRide
State createState() => _MyAppState();
}

class _MyAppState extends State {

late String token;
getToken() async {
token = (await FirebaseMessaging.instance.getToken())!;
Constants.fcmToken=token;
print(token);
}

var isBKNotification=false;
@OverRide
void initState() {
super.initState();
getToken();

}
@OverRide
Widget build(BuildContext context) {
return GetMaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
fontFamily: AppFontFamily.gothic,
useMaterial3: false,
appBarTheme: AppBarTheme(
surfaceTintColor: Colors.transparent,
systemOverlayStyle: SystemUiOverlayStyle(
statusBarColor: Colors.transparent
)
),
datePickerTheme: DatePickerThemeData(
headerForegroundColor: Colors.white,
backgroundColor: Colors.white,
headerBackgroundColor: Colors.blue,
dividerColor: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0), // this is the border radius of the picker
),
),
home:widget.initialRoute=="Profile"?ProfileScreen(): Splash(),

-----Notification service class-------------

class NotificationService {
final _messaging = FirebaseMessaging.instance;
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();

Future init() async {
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.requestNotificationsPermission();

const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings(
'@drawable/ic_launcher',
);

final DarwinInitializationSettings initializationSettingsIOS =
DarwinInitializationSettings(
onDidReceiveLocalNotification:
(int id, String? title, String? body, String? payload) async {
onSelectNotificationResponse;
},
);

var initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);

await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (payload) {
onSelectNotificationResponse(payload);
},

);

FirebaseMessaging.onMessage.listen(
(RemoteMessage event) {
showLocalNotification(
event.notification?.title??"",
event.notification?.body??"",
json.encode(event.data).toString(),
);
},
);

FirebaseMessaging.onMessageOpenedApp.listen(
(message) async {
await Get.to(DashBoard(index: 0));
},
);
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
}
Future onSelectNotificationResponse(
NotificationResponse notificationResponse) async {
final String? payload = notificationResponse.payload;
if (payload != null) {
await Get.to(DashBoard(index: 0));
}
}

void showLocalNotification(String? title, String? message, [String? payload]) async {
AndroidNotificationDetails androidPlatformChannelSpecifics = AndroidNotificationDetails(
title ?? '',
message ?? '',
importance: Importance.max,
priority: Priority.high,
enableVibration: true, // Enable vibration
playSound: true,
showWhen: false,
icon: "@drawable/ic_launcher"
);
DarwinNotificationDetails iosPlatformChannelSpecifics =
DarwinNotificationDetails(presentBadge: true, presentSound: true, presentAlert: true,);
NotificationDetails platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics,
iOS: iosPlatformChannelSpecifics,
);
await flutterLocalNotificationsPlugin.show(
0,
title,
message,
platformChannelSpecifics,
payload: payload,
);
}
}

------payload---------

{
"message": {
"token": "my device token",
"notification": {
"title": "Custom Notification",
"body": "This is a custom notification with actions.",
},
"android": {
"priority": "high"
}
}
}

@google-oss-bot google-oss-bot added Needs Attention This issue needs maintainer attention. and removed blocked: customer-response Waiting for customer response, e.g. more information was requested. labels Dec 13, 2024
@SelaseKay
Copy link
Contributor

Hi @DeepakYiron, the formatting still isn’t correct, and the code should be as minimal as possible. If you’re having trouble creating a minimal reproducible example, please refer to this guide for assistance.

@SelaseKay SelaseKay added blocked: customer-response Waiting for customer response, e.g. more information was requested. and removed Needs Attention This issue needs maintainer attention. labels Dec 13, 2024
@DeepakYiron
Copy link
Author

DeepakYiron commented Dec 13, 2024

NOTE:-This is the separate main file with all code merged at once place:
I have attached Notification Service class also

import 'dart:async';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import "package:flutter/material.dart";
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get/get.dart';
import 'package:notification_permissions/notification_permissions.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:io';

@pragma('vm:entry-point')
Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
NotificationService().showLocalNotification(
message.data['title']??"",
message.data['body']??"",
"",
);
}

Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
HttpOverrides.global = MyHttpOverrides();
NotificationService().init();
String initialRoute = await determineInitialRoute();
runApp(MyApp(initialRoute: initialRoute,));
}

Future determineInitialRoute() async {
FirebaseMessaging messaging = FirebaseMessaging.instance;
// Check if the app was launched from a notification
RemoteMessage? initialMessage = await messaging.getInitialMessage();
if (initialMessage != null) {
return "Profile";
}
return '';
}

class MyApp extends StatefulWidget {
MyApp({Key? key, required this.initialRoute}) : super(key: key);
final String initialRoute;
@OverRide
State createState() => _MyAppState();
}

class _MyAppState extends State {
@OverRide
void initState() {
super.initState();
}
@OverRide
Widget build(BuildContext context) {
/// i haven't share profile screen lets assume there will be screen,
return GetMaterialApp(
home:widget.initialRoute=="Profile"?ProfileScreen(): Splash(),
);
}
}

-----------------------------------------NOTIFICATION SERVICE CLASS----------------------------------
import 'dart:convert';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get/get.dart';

class NotificationService {
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();

Future init() async {
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.requestNotificationsPermission();

const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings(
  '@drawable/ic_launcher',
);

final DarwinInitializationSettings initializationSettingsIOS =
DarwinInitializationSettings(
  onDidReceiveLocalNotification:
      (int id, String? title, String? body, String? payload) async {
    onSelectNotificationResponse;
  },
);

var initializationSettings = InitializationSettings(
  android: initializationSettingsAndroid,
  iOS: initializationSettingsIOS,
);

await flutterLocalNotificationsPlugin.initialize(
  initializationSettings,
  onDidReceiveNotificationResponse: (payload) {
    onSelectNotificationResponse(payload);
  },
  onDidReceiveBackgroundNotificationResponse: onTapNotificationBackground,
);

FirebaseMessaging.onMessage.listen((RemoteMessage event) {
    showLocalNotification(
      event.data['title']??"",
      event.data['body']??"",
      "",
    );
  },
);

FirebaseMessaging.onMessageOpenedApp.listen((message) async {
  /// i haven't share DashBoard screen lets assume there will be screen,
    await Get.to(DashBoard());
  },
);

await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
  alert: true,
  badge: true,
  sound: true,
);

}

Future onSelectNotificationResponse(NotificationResponse notificationResponse) async {
final String? payload = notificationResponse.payload;
if (payload != null) {
/// i haven't share DashBoard screen lets assume there will be screen,
await Get.to(DashBoard(index: 0));
}
}

void showLocalNotification(String? title, String? message, [String? payload]) async {
AndroidNotificationDetails androidPlatformChannelSpecifics = AndroidNotificationDetails(
title ?? '',
message ?? '',
importance: Importance.max,
priority: Priority.high,
enableVibration: true, // Enable vibration
playSound: true,
showWhen: false,
icon: "@drawable/ic_launcher"
);
DarwinNotificationDetails iosPlatformChannelSpecifics =
DarwinNotificationDetails(presentBadge: true, presentSound: true, presentAlert: true,);
NotificationDetails platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics,
iOS: iosPlatformChannelSpecifics,
);
await flutterLocalNotificationsPlugin.show(
0,
title,
message,
platformChannelSpecifics,
payload: payload,
);
}
}

----------------------FIREBASE PACKAGES AND PUSH NOTIFICATION PAYLOAD------------------------------------

i have used these flutter packages:-
firebase_core: ^3.1.0
firebase_messaging: ^15.0.1
flutter_local_notifications: ^17.1.2

Notification payload is like below
{
"message": {
"token": "token",
"data": {
"title": "Custom Notification",
"body": "This is a custom notification with actions.",
},
"android": {
"priority": "high"
}
}
}

@google-oss-bot google-oss-bot added Needs Attention This issue needs maintainer attention. and removed blocked: customer-response Waiting for customer response, e.g. more information was requested. labels Dec 13, 2024
@DeepakYiron DeepakYiron changed the title When launch app from notification tap:- it is not navigating to specific screen || get initial message not working When launch app from notification tap(when app is terminated):- it is not navigating to specific screen || get initial message not working Dec 13, 2024
@SelaseKay
Copy link
Contributor

Kindly create a sample repository reproducing the issue and share the link here.

@SelaseKay SelaseKay added blocked: customer-response Waiting for customer response, e.g. more information was requested. and removed Needs Attention This issue needs maintainer attention. labels Dec 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked: customer-response Waiting for customer response, e.g. more information was requested. platform: android Issues / PRs which are specifically for Android. plugin: messaging type: bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants