I’m encountering an issue with Firebase Cloud Messaging (FCM) notifications in my Flutter app. Specifically, when opening an article from a notification, closing the app, and then reopening it manually, the app reopens the same article instead of starting normally.
When reopening the app manually, it should start on the home screen (or the default screen) and not automatically navigate to the last article from the previous notification.
Investigation and Possible Causes
Handling Notification Clicks in Background
FirebaseMessaging.onMessageOpenedApp.listen((message) async {
print('\n🔔 Notification opened from background:');
print('📦 Message details:');
print('ID: ${message.messageId}');
print('Data: ${message.data}');
if (message.data['post_id'] != null) {
print('✅ Post ID found: ${message.data['post_id']}');
final prefs = await SharedPreferences.getInstance();
await prefs.setString('pending_article_id', message.data['post_id']);
print('✅ Post ID saved for later opening');
}
});
Handling App Start with Pending Notifications
Future<String?> checkPendingArticle() async {
final prefs = await SharedPreferences.getInstance();
final pendingArticleId = prefs.getString('pending_article_id');
if (pendingArticleId != null) {
await prefs.remove('pending_article_id');
return pendingArticleId;
}
return null;
}
Opening the Article if a Pending ID Exists
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// Check if the app was launched from a notification
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async {
if (message.data['post_id'] != null) {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('pending_article_id', message.data['post_id']);
}
});
// Initialize notification controller
await NotificationController().initialize();
runApp(
ChangeNotifierProvider(
create: (_) => ThemeProvider(),
child: const MyApp(),
),
);
}
How can I ensure that when reopening the app manually, it does not automatically navigate to the last opened article from the notification? Could this be an issue with how FirebaseMessaging.instance.getInitialMessage() is handled, and if so, what is the best way to reset the stored article ID properly?
Any insights or suggestions on handling this behavior correctly would be greatly appreciated!
You do not need to store the post_id in preferences, If you need it somewhere else during the app session, consider storing it using Provider or any other state management you might be using.
Your initialization should go like this
Future<void> initNotification() {
// Triggered when app is opened from background on notification tap
FirebaseMessaging.onMessageOpenedApp.listen((message) {
final postId = message.data['post_id'] as String?
if (postId != null) {
_handlePostIdNotification(postId);
}
}):
// Triggered when notification is tapped when in foreground
FirebaseMessaging.onMessagelisten((message) {
final postId = message.data['post_id'] as String?
if (postId != null) {
_handlePostIdNotification(postId);
}
}):
// Returns a remote message if the app was started by notification tap
final message = await FirebaseMessaging.instance.getInitialMessage();
final postId = message.data['post_id'] as String?
if (postId != null) {
_handlePostIdNotification(postId);
}
}
You should call initNotification() in the initState of a widget below your ChangeNotifierProvider, so you can use provider to keep postId in memory