Firebase推送通知无法打开URL问题排查求助
问题排查与解决方案
我仔细看了你的代码、推送Payload和Manifest配置,找到了几个导致点击通知无法打开URL的关键问题:
1. 核心疏漏:自定义通知逻辑完全没执行
你在onMessageReceived里正确获取了通知的标题、内容、click_action和URL,但从头到尾没有调用你写好的sendNotification方法!这直接导致:
- 应用前台时,系统不会自动弹出通知,你的自定义跳转逻辑根本没机会运行;
- 应用后台时,Firebase会直接用系统托盘处理
notification字段的推送,完全走默认的click_action逻辑,完全忽略你的代码逻辑。
2. PendingIntent 适配问题
你的PendingIntent.getActivity使用的flag是0,在Android 12及以上版本,这种写法会导致PendingIntent无法正常生效,必须指定FLAG_IMMUTABLE或FLAG_UPDATE_CURRENT(根据业务需求选择)。
3. 后台推送的系统行为限制
当应用处于后台时,Firebase收到包含notification字段的推送时,会由系统直接展示通知,此时notification里的link会被click_action覆盖(系统优先处理click_action)。要解决这个问题,需要把URL放在data字段中,或者使用纯data推送,确保无论前台后台都能触发onMessageReceived。
修复后的完整代码
1. 修改MyFirebaseMessagingService
public class MyFirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService { private static final String TAG = "FirebaseMessagingServic"; public MyFirebaseMessagingService() {} @Override public void onMessageReceived(RemoteMessage remoteMessage) { String title = ""; String message = ""; String clickAction = "MAIN_PAGE"; // 默认跳转Activity Uri targetUri = null; // 优先处理data字段(兼容后台推送场景) if (remoteMessage.getData().size() > 0) { Log.d(TAG, "Message data payload: " + remoteMessage.getData()); try { JSONObject data = new JSONObject(remoteMessage.getData()); // 从data里读取URL(后台推送时也能拿到) String url = data.optString("link"); if (!TextUtils.isEmpty(url)) { targetUri = Uri.parse(url); } // 从data里读取标题、内容、点击动作 title = data.optString("title", title); message = data.optString("body", message); clickAction = data.optString("click_action", clickAction); } catch (JSONException e) { e.printStackTrace(); } } // 处理notification字段(仅前台推送时生效) if (remoteMessage.getNotification() != null) { if (TextUtils.isEmpty(title)) { title = remoteMessage.getNotification().getTitle(); } if (TextUtils.isEmpty(message)) { message = remoteMessage.getNotification().getBody(); } if (targetUri == null) { targetUri = remoteMessage.getNotification().getLink(); } if (TextUtils.isEmpty(clickAction)) { clickAction = remoteMessage.getNotification().getClickAction(); } Log.d(TAG, "Message Notification Title: " + title); Log.d(TAG, "Message Notification Body: " + message); Log.d(TAG, "Message Notification click_action: " + clickAction); Log.d(TAG, "Message Notification url: " + targetUri); } // 关键:调用自定义通知方法! if (!TextUtils.isEmpty(title) || !TextUtils.isEmpty(message)) { sendNotification(title, message, clickAction, targetUri); } } @Override public void onDeletedMessages() {} private void sendNotification(String title, String messageBody, String click_action, Uri uri) { Intent intent; if (uri != null) { intent = new Intent(Intent.ACTION_VIEW); intent.setData(uri); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 避免栈冲突 } else { intent = new Intent(click_action); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } // 适配Android 12+的PendingIntent Flag int pendingIntentFlag; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { pendingIntentFlag = PendingIntent.FLAG_IMMUTABLE; } else { pendingIntentFlag = PendingIntent.FLAG_UPDATE_CURRENT; } PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, pendingIntentFlag); Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.app_logo_final) .setContentTitle(TextUtils.isEmpty(title) ? "PushNotification" : title) .setContentText(messageBody) .setAutoCancel(true) .setSound(defaultSoundUri) .setContentIntent(pendingIntent); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); // 用随机ID避免通知被覆盖(可选) notificationManager.notify((int) System.currentTimeMillis(), notificationBuilder.build()); } }
2. 修改推送Payload(推荐纯Data推送,兼容前后台)
{ "to": "/topics/NEWS", "data": { "extra_information": "This is some extra information", "title": "Test title: http://www.google.com", "body": "Test body: http://www.google.com", "link": "http://www.google.com", "click_action": "MAIN_PAGE" } }
如果一定要保留notification字段,也要确保data里包含link,这样后台推送时也能读取到URL。
3. Manifest配置无需修改(保持现有即可)
验证步骤
- 重新编译安装应用;
- 发送修改后的Payload;
- 分别测试应用前台、后台、杀死状态下的通知跳转:
- 存在URL时,点击通知会打开浏览器加载对应链接;
- 无URL时,会打开指定的
MainScreenActivity。
内容的提问来源于stack exchange,提问作者CuriousPaul
相关产品推荐
相关产品推荐

