Firebase Topic通知跳转逻辑失效及送达异常求助
问题描述
开发请假应用时,计划通过Firebase Topic实现跨Activity通知传递(MainActivity→DepartmentHead→Admin),遇到以下问题:
- FirebaseMessagingService中的IF条件判断完全无效
- 两个不同Topic的通知无法正确送达对应页面,点击通知无法跳转至目标Activity
- 需要解决通知携带数据的问题
应用无崩溃,但通知功能无法正常工作。
关键代码
FirebaseMessagingService核心代码
public class FirebaseNoficationservices extends FirebaseMessagingService { private final String CHANNEL_ID="channel_id"; Intent intent; public void onMessageReceived(@NonNull RemoteMessage remoteMessage) { super.onMessageReceived(remoteMessage); Log.d("remote", remoteMessage.getData().toString()); if((FirebaseMessaging.getInstance().subscribeToTopic("ahmedraza"))!=null){ intent = new Intent(getApplicationContext(), DepartmentHead.class); } else if((FirebaseMessaging.getInstance().subscribeToTopic("ahmedraza"))!=null){ intent = new Intent(getApplicationContext(), Admin.class); } NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); int notificationId = new Random().nextInt(); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { createNotificationChannel(manager); } intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.putExtra("key", remoteMessage.getData().get("name")); PendingIntent intent1 = PendingIntent.getActivities(this, 0, new Intent[]{intent}, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE); Notification notification; notification = new NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle(remoteMessage.getData().get(getString(R.string.name))) .setContentText(remoteMessage.getData().get(getString(R.string.department))) .setSmallIcon(R.drawable.rx_notification) .setAutoCancel(true) .setContentIntent(intent1) .build(); manager.notify(notificationId, notification); } @RequiresApi(api = Build.VERSION_CODES.O) private void createNotificationChannel(NotificationManager manager) { NotificationChannel channel=new NotificationChannel(CHANNEL_ID,"channelName",NotificationManager.IMPORTANCE_HIGH); channel.setDescription("My description"); channel.enableLights(true); channel.setLightColor(android.R.color.white); manager.createNotificationChannel(channel); } }
MainActivity发送通知代码
if(sendtoDepthead.isChecked()) { PushNotification notification = new PushNotification(new notificationData(fulnamee.getText().toString(), spinner.getSelectedItem().toString()), TOPIC); sendNotification(notification); Toast.makeText(MainActivity.this, "notification sent to manager", Toast.LENGTH_SHORT).show(); } if(sendtoGeneralmanager.isChecked()){ PushNotification notification = new PushNotification(new notificationData(fulnamee.getText().toString(), spinner.getSelectedItem().toString()), TOPICS); sendNotification(notification); Toast.makeText(MainActivity.this, "notification sent to manager", Toast.LENGTH_SHORT).show(); }
DepartmentHead订阅及转发代码
FirebaseMessaging.getInstance().subscribeToTopic(TOPIC); FirebaseMessaging.getInstance().subscribeToTopic(TOPIC) .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { String msg = "Subscribed"; if (!task.isSuccessful()) { msg = "Subscribe failed"; } Log.d(TAG, msg); Toast.makeText(DepartmentHead.this, msg, Toast.LENGTH_SHORT).show(); } }); // 转发到Admin PushNotification notification=new PushNotification(new notificationData(nam.getText().toString(),dept.getText().toString()),TOPICS); sendNotification(notification); Toast.makeText(DepartmentHead.this,"notification sent to manager",Toast.LENGTH_SHORT).show();
Admin订阅代码
FirebaseMessaging.getInstance().subscribeToTopic(TOPICS) .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { String msg = "Subscribed"; if (!task.isSuccessful()) { msg = "Subscribe failed"; } Log.d(TAG, msg); Toast.makeText(Admin.this, msg, Toast.LENGTH_SHORT).show(); } });
解决方案
1. 修复条件判断逻辑
原代码中用FirebaseMessaging.getInstance().subscribeToTopic()判断订阅状态完全错误,这个方法是执行订阅操作,返回的Task对象永远不为null,导致条件失效。
正确做法:通过RemoteMessage的from字段判断消息来源Topic(格式为/topics/xxx),以此区分目标页面。
2. 修正通知跳转逻辑
原代码误用PendingIntent.getActivities(),应改为PendingIntent.getActivity();同时设置正确的Intent Flag,避免页面栈混乱。
3. 确保通知数据正确携带
发送端要保证数据字段与接收端key一致,接收端提取数据后通过Intent传递到目标Activity。
修正后的关键代码
FirebaseMessagingService代码
public class FirebaseNoficationservices extends FirebaseMessagingService { private final String CHANNEL_ID = "channel_id"; // 与发送端的Topic常量保持一致 private static final String TOPIC_DEPT_HEAD = "ahmedraza"; private static final String TOPIC_ADMIN = "admin_topic"; @Override public void onMessageReceived(@NonNull RemoteMessage remoteMessage) { super.onMessageReceived(remoteMessage); Log.d("remote", remoteMessage.getData().toString()); Intent intent = null; // 通过消息来源Topic判断目标页面 String fromTopic = remoteMessage.getFrom(); if (fromTopic != null && fromTopic.equals("/topics/" + TOPIC_DEPT_HEAD)) { intent = new Intent(this, DepartmentHead.class); } else if (fromTopic != null && fromTopic.equals("/topics/" + TOPIC_ADMIN)) { intent = new Intent(this, Admin.class); } // 兜底处理,避免intent为null if (intent == null) { intent = new Intent(this, MainActivity.class); } NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); int notificationId = new Random().nextInt(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { createNotificationChannel(manager); } // 设置Intent Flag,确保跳转后页面栈正确 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); // 携带通知数据 String userName = remoteMessage.getData().get("name"); String department = remoteMessage.getData().get("department"); intent.putExtra("key_name", userName); intent.putExtra("key_department", department); // 使用getActivity创建正确的PendingIntent,用notificationId作为requestCode避免重复 PendingIntent pendingIntent = PendingIntent.getActivity( this, notificationId, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE ); Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle(userName) .setContentText(department) .setSmallIcon(R.drawable.rx_notification) .setAutoCancel(true) .setContentIntent(pendingIntent) .build(); manager.notify(notificationId, notification); } @RequiresApi(api = Build.VERSION_CODES.O) private void createNotificationChannel(NotificationManager manager) { NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "请假通知", NotificationManager.IMPORTANCE_HIGH); channel.setDescription("处理请假申请的通知渠道"); channel.enableLights(true); channel.setLightColor(Color.WHITE); manager.createNotificationChannel(channel); } }
发送端数据类规范
确保notificationData的字段名与接收端一致,且包含getter方法(Firebase序列化需要):
public class notificationData { private String name; private String department; public notificationData(String name, String department) { this.name = name; this.department = department; } public String getName() { return name; } public String getDepartment() { return department; } }
订阅逻辑优化
每个页面只订阅对应Topic,避免重复订阅:
- DepartmentHead仅订阅
TOPIC_DEPT_HEAD - Admin仅订阅
TOPIC_ADMIN
内容的提问来源于stack exchange,提问作者Ahmed
相关产品推荐
相关产品推荐

