You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 21:24:03