Ionic 3 FCM:后台/关闭状态下点击通知无法打开指定页面
Let me break down your current setup first, then walk through actionable fixes to get the navigation working properly:
Current Working Behavior
- Push notifications come through successfully when the app is in the background or fully killed
- Tapping the notification correctly pulls in payload data (including
user_id,user_name, andtypefrom thedatafield) - Your FCM payload structure looks like this:
{ "notification": { "title": "Chat Messages", "body": "You have received chat messages from ${userName}", "sound": "default", "click_action":"FCM_PLUGIN_ACTIVITY", "icon":"fcm_push_icon" }, "data": { "user_id" : from_user_id, "user_name" : userName, "type" : notification_type } }
The Core Problem
Right now, tapping the notification only launches your app's default home screen instead of navigating to your desired specific page (like a chat thread).
Fixes to Implement
1. Align click_action with AndroidManifest Intent Filter
The click_action value in your payload must exactly match an intent filter in your app's target activity. Open your AndroidManifest.xml and update your main activity (or the activity you want to trigger) with this:
<activity android:name=".MainActivity" android:launchMode="singleTop"> <!-- Prevents recreating the activity if it's already open --> <intent-filter> <action android:name="FCM_PLUGIN_ACTIVITY" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
Pro tip: Using singleTop ensures new notification intents are sent to onNewIntent() instead of spawning a duplicate activity.
2. Handle Intent Data to Trigger Navigation
Once the activity launches via the notification intent, you need to extract the payload data and route to your specific page. Here's how to do it for common frameworks:
Native Android (Kotlin)
Add this logic to your MainActivity:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Handle intent when app was killed and needs to be launched fresh handleNotificationIntent(intent) } override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) // Handle intent when app was already running in background handleNotificationIntent(intent) } private fun handleNotificationIntent(intent: Intent?) { intent?.extras?.let { extras -> val userId = extras.getString("user_id") val userName = extras.getString("user_name") val notificationType = extras.getString("type") // Navigate to your chat page if the notification is a chat type if (userId != null && notificationType == "chat") { val chatIntent = Intent(this, ChatActivity::class.java) chatIntent.putExtra("user_id", userId) chatIntent.putExtra("user_name", userName) startActivity(chatIntent) } } }
Flutter (with firebase_messaging)
Add stream listeners to handle both killed and background states:
@override void initState() { super.initState(); // Handle taps when app was fully killed FirebaseMessaging.instance.getInitialMessage().then((message) { if (message != null) { _navigateToTargetPage(message.data); } }); // Handle taps when app was in background FirebaseMessaging.onMessageOpenedApp.listen((message) { _navigateToTargetPage(message.data); }); } void _navigateToTargetPage(Map<String, dynamic> data) { final userId = data['user_id']; final userName = data['user_name']; final notificationType = data['type']; if (notificationType == 'chat' && userId != null) { // Use your app's navigation setup to go to the chat screen Navigator.push( context, MaterialPageRoute( builder: (context) => ChatScreen(userId: userId, userName: userName), ), ); } }
3. Validate Payload Data Format
Double-check your backend sends data fields as strings (FCM can misparse non-string values like integers). If you need numeric IDs, convert them to strings in the payload and parse them back in your app.
Quick Troubleshooting Checks
- Confirm
click_actionin the payload is case-sensitive and matches the AndroidManifest intent filter exactly - For iOS, handle taps in
UNUserNotificationCenterDelegate'sdidReceiveNotificationResponsemethod - Test with the app fully killed (swiped away) to ensure the cold-launch navigation logic works
内容的提问来源于stack exchange,提问作者kelvin wong

