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

如何使用Retrofit在Android设备间发送FCM通知?

解决Retrofit发送FCM通知的IllegalArgumentException问题

看起来你遇到的java.lang.IllegalArgumentException大概率是接口定义里的几个错误导致的,我帮你梳理下问题点并给出修正方案:

核心问题分析

  1. 混用@Field和@Body:Retrofit不允许在同一个接口方法里同时使用表单字段(@Field)和请求体(@Body)。FCM的发送接口要求JSON格式的POST请求,所有参数都应该封装在请求体里,而不是拆分出来用@Field传递。
  2. Authorization头格式错误:你的Header里Authorization : key=...的冒号后面多了个空格,正确格式应该是Authorization: key=...,这个空格可能导致认证失败或者请求格式不被FCM服务器识别。

修正后的代码实现

1. 修正ApiInterface定义

把@Field去掉,将to字段整合到请求体中:

public interface ApiInterface {
    @Headers("Authorization: key=AAAA4Ubio1Q:APA91bGWkw84b1XX2nnnOKn8MO25U2giLRXXXTUkXidojFluZk_qKXXXlS27oMZZV5goTQdwRtpdmvI1iAPRZZDNKz6c-mpU6nvHZJ-Jg9f1fQ5NdttftqUpqwAkObLEEX26VFDDbXN8")
    @POST("fcm/send")
    Call<ResponseBody> sendChatNotification(@Body RequestNotification requestNotification);
}

2. 定义正确的请求体实体类

需要创建对应FCM JSON结构的实体类,包含to和notification字段:

// 外层请求体
public class RequestNotification {
    private String to;
    private NotificationContent notification;

    public RequestNotification(String to, NotificationContent notification) {
        this.to = to;
        this.notification = notification;
    }

    // 生成Getter和Setter方法,或者用Lombok的@Data注解简化
}

// 通知内容实体
public class NotificationContent {
    private String title;
    private String body;

    public NotificationContent(String title, String body) {
        this.title = title;
        this.body = body;
    }

    // 生成Getter和Setter方法
}

3. 调用接口发送通知的示例

// 构建通知内容
NotificationContent content = new NotificationContent("新消息", "这是一条来自其他设备的FCM通知");
// 构建请求体,传入目标设备的FCM Token
RequestNotification request = new RequestNotification("目标设备的FCM Token", content);

// 初始化Retrofit并调用接口(假设你已经有Retrofit实例)
ApiInterface apiService = RetrofitClient.getInstance().create(ApiInterface.class);
Call<ResponseBody> call = apiService.sendChatNotification(request);

call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        if (response.isSuccessful()) {
            // 通知发送成功,处理后续逻辑
            Log.d("FCM", "通知发送成功");
        } else {
            // 处理失败响应,比如打印错误信息
            try {
                Log.e("FCM", "发送失败:" + response.errorBody().string());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        // 处理网络异常
        Log.e("FCM", "网络请求失败:" + t.getMessage());
    }
});

额外注意事项

  • Retrofit配置:确保你的Retrofit实例添加了JSON转换器,比如GsonConverterFactory,否则无法将实体类序列化为JSON请求体:
    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://fcm.googleapis.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();
    
  • 安全建议:不要在客户端硬编码FCM Server Key!这会有密钥泄露的风险,建议通过自己的后端服务器中转发送FCM通知,客户端只需要调用自己的后端接口即可。
  • Token有效性:确保目标设备的FCM Token是最新且有效的,如果Token过期或无效,FCM服务器会返回对应的错误信息。

内容的提问来源于stack exchange,提问作者iamkdblue

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:44:26