I am trying to figure out if app is opened by clicking on push notification or by clicking on app launcher icon, scenario is that i want to check if app is opened by clicking push notification then i'll load data on home screen from cache other wise i need to get data from api.
i am using getInitialMessage() method but its not working in my case
here is my code
Class NotificationService{
String? msg;
bool fromNotification = false;
final _firebaseMessaging = FirebaseMessaging.instance;
Future<void> initNotification() async
{
RemoteMessage? initialMessage = await _firebaseMessaging.getInitialMessage();
if (initialMessage != null)
{ msg = initialMessage.toString();
fromNotification = true;
}
}
}
I have achieved this through the onMessageOpenedApp function. See my code below.
Define a PushNotificationHandler class as shown below:
class PushNotificationHandler {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
final localNotifications = FlutterLocalNotificationsPlugin();
bool _openedFromNotification = false;
// Android Channel
final androidChannel = const AndroidNotificationChannel(
'test_channel_name', "Test Channel",
description: "This is a TEST Channel",
importance: Importance.defaultImportance);
Future<bool> initialize() async {
// Initialize Firebase Messaging
await _firebaseMessaging.requestPermission();
// Get the FCM token to use when sending notifications
String? fcmToken;
if (Platform.isIOS) {
fcmToken = await _firebaseMessaging.getAPNSToken() ?? "";
final platform = localNotifications.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin>();
} else if (Platform.isAndroid) {
fcmToken = await _firebaseMessaging.getToken() ?? "";
final platform = localNotifications.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>();
await platform?.createNotificationChannel(androidChannel);
}
// display the token so you can use it to send notifications
if (fcmToken != null) {
print('FCMToken: ${fcmToken}');
}
// Handle notifications when the app is in the background
FirebaseMessaging.onBackgroundMessage(_handleBackgroundMessage);
// Handle notifications when the app is in the foreground
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
});
// Handle notification clicks when the app is terminated
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
// Handle notification clicks here
// Set a flag or send a message to the app indicating it was opened from a notification
_openedFromNotification = true;
});
return _openedFromNotification;
}
The function initialize() will return bool.
Define your app as shown below:
class MyNotificationApp extends StatefulWidget {
@override
_MyNotificationAppState createState() => _MyNotificationAppState();
}
class _MyNotificationAppState extends State<MyNotificationApp> {
final PushNotificationHandler _pushNotificationHandler =
PushNotificationHandler();
bool _appOpenedFromNotification = false;
@override
void initState() {
super.initState();
print('OPENING_APP');
_initializePushNotifications();
}
// Initialize the notifications
Future<void> _initializePushNotifications() async {
// Wait for the initialization to complete
bool result = await _pushNotificationHandler.initialize();
setState(() {
_appOpenedFromNotification = result;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
home: MyHomePage(appOpenedFromNotification: _appOpenedFromNotification),
);
}
}
In the MyHomePage widget, I am printing out how the app has been opened.
class MyHomePage extends StatelessWidget {
final bool appOpenedFromNotification;
const MyHomePage({super.key, required this.appOpenedFromNotification});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
),
body: Center(
child: Text(appOpenedFromNotification
? 'Opened from notification'
: 'Opened from launcher'),
),
);
}
}
This should solve the issue you are having.