使用PHP发送多设备FCM通知时安卓前台应用崩溃问题求助
问题根因
你当前PHP脚本发送的是FCM数据类型消息(data message),仅携带了data字段,未携带notification字段,但安卓端的onMessageReceived方法直接调用remoteMessage.getNotification().getTitle()和getBody(),此时getNotification()会返回null,触发空指针异常导致应用崩溃。单独测试通知功能正常是因为测试时发送的是带notification字段的通知类型消息。
解决方案
你可以选择以下任意一种方案修复,建议同时做两侧的兼容处理:
方案1:修改PHP侧推送逻辑,新增notification字段
修改FCM请求的$fields参数,增加通知字段,让安卓端可以直接从getNotification()获取内容:
$fields = array( 'registration_ids' => $tokens, 'data' => $message, // 新增notification通知字段 'notification' => array( 'title' => '测试推送', 'body' => 'FCM PUSH NOTIFICATION TEST MESSAGE' ) );
方案2:修改安卓侧代码,加空校验和兼容逻辑
需要补充空值判断、通知通道创建、安卓版本适配三个部分的逻辑,修改后代码如下:
public class FirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService { private static final String CHANNEL_ID = "101"; @Override public void onCreate() { super.onCreate(); // 安卓8.0及以上必须提前创建通知通道,否则无法显示通知甚至崩溃 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { CharSequence name = "推送通知通道"; String description = "接收FCM推送通知"; int importance = NotificationManager.IMPORTANCE_DEFAULT; NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance); channel.setDescription(description); NotificationManager notificationManager = getSystemService(NotificationManager.class); notificationManager.createNotificationChannel(channel); } } @Override public void onMessageReceived(@NonNull RemoteMessage remoteMessage) { Intent intent = new Intent(this, LoginActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); // 安卓12及以上必须指定PendingIntent的可变性,否则会触发异常 int flag = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0; PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, flag); String title = "新通知"; String content = "您收到一条新消息"; // 优先读取notification字段内容,判空避免空指针 if(remoteMessage.getNotification() != null){ if(remoteMessage.getNotification().getTitle() != null){ title = remoteMessage.getNotification().getTitle(); } if(remoteMessage.getNotification().getBody() != null){ content = remoteMessage.getNotification().getBody(); } } // 没有notification字段时读取data字段的自定义内容 else if(remoteMessage.getData().size() > 0){ content = remoteMessage.getData().get("message"); } NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.ic_add) .setContentTitle(title) .setContentText(content) .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setContentIntent(pendingIntent) .setAutoCancel(true); NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); // 安卓13及以上需要判断通知权限,无权限时不要调用notify if (ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) { notificationManager.notify(1, builder.build()); } } @Override public void onNewToken(@NonNull String s) { Log.e("TAG", "onNewToken: "+s ); } }
其他排查点
如果修改后仍然崩溃,可按以下步骤定位:
- 查看Android Studio Logcat中的崩溃堆栈信息,准确定位报错代码行
- 检查安卓13及以上版本是否动态申请了
POST_NOTIFICATIONS通知权限 - 确认
R.drawable.ic_add小图标资源存在,资源缺失也会导致通知构建失败 - 检查AndroidManifest.xml中是否正确注册了
FirebaseMessagingService服务
内容的提问来源于stack exchange,提问作者aziz laroussi
相关产品推荐
相关产品推荐

