Android中使用Retrofit2调用FCM创建设备组通知时返回400错误的解决方案
首先,咱们得先搞清楚FCM返回400错误的具体原因——400只是“请求格式错误”的通用提示,FCM其实会返回详细的错误信息,这是排查的关键。
第一步:获取FCM的详细错误响应
先修改你的onResponse方法,打印出错误响应的具体内容,这样就能知道到底是哪个字段出问题了:
@Override public void onResponse(@NotNull Call<FirebaseMessagingDeviceGroupResponseModel> call, @NotNull Response<FirebaseMessagingDeviceGroupResponseModel> response) { if (response.isSuccessful() && response.body() != null) { driversNotificationGroupId = response.body().getNotificationKey(); // 处理通知密钥 } else { Log.e(TAG,"Response Is Empty :: " + response); // 打印FCM返回的错误详情 if (response.errorBody() != null) { try { String errorDetails = response.errorBody().string(); Log.e(TAG, "FCM错误详情: " + errorDetails); } catch (IOException e) { e.printStackTrace(); } } } }
比如,如果是registration_ids为空,FCM会明确告诉你这个字段缺失或者无效。
第二步:验证Retrofit序列化的JSON是否正确
Postman里的JSON是有效的,但Retrofit把你的请求模型转成JSON时可能出了问题。在发送请求前,把模型转成字符串看看:
// 先导入Gson import com.google.gson.Gson; // 在创建请求模型后添加这段代码 Gson gson = new Gson(); String requestJson = gson.toJson(firebaseMessagingDeviceGroupRequestModel); Log.d(TAG, "实际发送的JSON: " + requestJson);
对比这个JSON和你在Postman里用的,看看有没有字段缺失、拼写错误(比如字段名是不是和FCM要求的完全一致)。
常见问题的修复方案
根据我处理这类问题的经验,大概率是下面几个问题之一:
1. 请求模型缺少无参构造函数
Gson在序列化对象时,默认需要无参构造函数(哪怕你是手动实例化的)。给FirebaseMessagingDeviceGroupRequestModel添加无参构造函数:
public class FirebaseMessagingDeviceGroupRequestModel { // 现有字段和方法... // 添加无参构造函数 public FirebaseMessagingDeviceGroupRequestModel() { } }
2. 确认registration_ids不为空且有效
确保driverKeys列表里的注册ID是有效的(和你在Postman里用的完全一致),而且列表不能为空——FCM会因为空的registration_ids返回400错误。
3. 检查Header的格式是否正确
确认Authorization和project_id的格式完全正确:
Authorization: key=你的服务器密钥:服务器密钥要从Firebase控制台的「云消息传递」页面获取,别用错成了Web API密钥或者其他密钥project_id: 你的Firebase项目ID:是项目的ID(比如my-project-12345),不是项目编号
4. 确保Gson转换器配置正确
如果你自定义了Gson实例,别禁用了SerializedName的支持。默认的GsonConverterFactory.create()是没问题的,但如果是自定义Gson,要确保:
Gson gson = new GsonBuilder() .setLenient() // 有时候严格的JSON解析会导致问题,可选开启 .create(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://fcm.googleapis.com/") .addConverterFactory(GsonConverterFactory.create(gson)) .build();
测试修复后的代码
修改完之后,重新运行App,查看日志里的序列化JSON是否和Postman里的一致,再看错误详情是否消失。如果一切正常,你应该就能成功获取到notification_key了。
内容的提问来源于stack exchange,提问作者S. Joshi

