使用FCM批量推送通知异常:仅能推送给首个设备的问题求助
问题解决步骤
1. 修复Android端Activity的推送逻辑
你当前在循环中每添加一个Token就调用一次推送接口,导致每次请求的Token列表是累加状态(如[token1]→[token1,token2]),还会重复发起无效请求。正确做法是先收集全所有Token,再统一调用接口:
binding.btnSend.setOnClickListener(v -> { db.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { List<String> tokens = new ArrayList<>(); // 先一次性收集所有设备Token for (DataSnapshot dataSnapshot: snapshot.getChildren()){ User_Model userModel = dataSnapshot.getValue(User_Model.class); tokens.add(userModel.getToken()); } // 收集完成后再发起推送请求 if (!tokens.isEmpty()) { API api = retrofit.create(API.class); Call<ResponseBody> call = api.sendNotification( tokens, binding.etNotificationTitle.getText().toString(), binding.etNotificationBody.getText().toString() ); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { // 可添加推送发起成功的提示逻辑 } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { // 处理请求失败场景 } }); } } @Override public void onCancelled(@NonNull DatabaseError error) { Toast.makeText(AddNotificationActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show(); } }); });
2. 修复Cloud Function的FCM请求格式
你的后端当前把传入的Token列表直接赋值给message.token,但FCM批量推送需要使用**tokens数组字段**,且消息结构要符合多播格式。修改index.js中的请求部分:
router.post('/send', function(req, res){ getAccessToken().then(function(access_token){ var title = req.body.title; var body = req.body.body; var tokens = req.body.token; // 对应前端传入的Token数组 // 构建FCM多播消息结构 const message = { notification: { body: body, title: title, }, tokens: tokens // 替换原单个token字段为tokens数组 }; request.post({ headers:{ Authorization: 'Bearer '+access_token, 'Content-Type': 'application/json' // 明确指定JSON类型请求头 }, url: "https://fcm.googleapis.com/v1/projects/你的项目ID/messages:send", // 替换为你的FCM v1接口地址 body: JSON.stringify({ message: message }) }, function(error, response, body){ res.end(body); console.log(body); }); }); });
3. 关键注意事项
- 批量推送限制:FCM一次最多支持推送500个设备Token,若你的Token数量超过500,需要在后端将列表拆分为多个500以内的批次分别发送。
- 请求头校验:必须添加
Content-Type: application/json,否则FCM无法正确解析请求体。 - 结果排查:FCM批量推送会返回每个Token的推送状态,可在后端解析返回的
responses数组,记录失败的Token以便后续排查。
4. 可选优化:推送结果解析
在后端添加结果解析逻辑,方便定位推送失败的设备:
// 在request的回调函数中添加 function(error, response, body){ if (!error && response.statusCode === 200) { const result = JSON.parse(body); result.responses.forEach((resp, index) => { if (resp.success) { console.log(`Token ${tokens[index]} 推送成功`); } else { console.log(`Token ${tokens[index]} 推送失败: ${resp.error.message}`); } }); } res.end(body); }
内容的提问来源于stack exchange,提问作者Taha Younis
相关产品推荐
相关产品推荐

