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

FCM HTTP v1 API偶发403错误(SenderId mismatch)排查求助

排查FCM HTTP v1 API偶尔出现403(SenderId mismatch)问题的建议

已迁移至FCM HTTP v1 API,大部分消息发送正常,但每日少量消息返回403错误,错误信息明确为SenderId mismatch,配置、服务状态、认证令牌均正常,发送代码如下:

try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
    String urlFinal = FCM_URL.replace("nomeprojeto", Projetos.getProjetoId(keyStore));
    HttpPost post = new HttpPost(urlFinal);
    // Set headers
    post.setHeader("Content-type", "application/json");
    post.setHeader("Authorization", "Bearer " + getAccessToken(keyStore));
    // Json generation
    Root mensagem = new Root();
    mensagem.message.notification = msg.notification;
    mensagem.message.token = msg.token;
    mensagem.message.data = msg.data;
    String json = new ObjectMapper().writeValueAsString(mensagem);
    //System.out.println(json);
    post.setEntity(new StringEntity(json, "UTF-8"));
    // Call http
    HttpResponse response = client.execute(post);
    int statusCode = response.getStatusLine().getStatusCode();
    // Validate response.
    if (statusCode == 200) {
        pushBean.log(msg, keyStore);
        System.out.println("push processado - " + new Date());
        return;
    }
    if (statusCode == 404) {
        // documentação indica para não retentar no 400 e 404
        String error = statusCode + " - Token FCM não encontrado: " + msg.token;
        pushBean.logErro(msg, keyStore, error + msg.token);
        return;
    }
    if (statusCode == 403) {
        // documentação indica para não retentar no 403
        String error = "403 - Token FCM não aceito: " + msg.token;
        pushBean.logErro(msg, keyStore, error + msg.token);
        return;
    }
    if (statusCode != 200) {
        String error = "Erro ao efetuar envio do FCM, código do retorno = %d";
        error = String.format(error, statusCode);
        FCMException ex = new FCMException(error);
        throw ex;
    }
}

返回的403错误JSON:

{
  "error": {
    "code": 403,
    "message": "SenderId mismatch",
    "status": "PERMISSION_DENIED",
    "details": [
      {
        "@type": "type.googleapis.com/google.firebase.fcm.v1.FcmError",
        "errorCode": "SENDER_ID_MISMATCH"
      }
    ]
  }
}

排查建议

  • 核对令牌所属SenderId:出错的令牌大概率是从其他Firebase项目注册生成的,和当前发送请求用的项目SenderId不匹配。可以解析令牌提取SenderId信息验证,或者检查客户端注册时用的是当前项目的配置文件(google-services.json/GoogleService-Info.plist)。
  • 清理跨项目无效令牌:维护令牌存储时,定期清理来自其他项目的令牌;或者客户端注册成功后,把令牌和对应项目标识绑定,发送时确保用对应项目的认证信息发送。
  • 检查多项目发送逻辑:如果服务需要给多个Firebase项目发消息,确认Projetos.getProjetoId(keyStore)和getAccessToken(keyStore)是否和当前令牌所属项目匹配,别搞混项目标识和认证令牌。
  • 同步令牌生命周期:用户切换应用环境(比如从测试项目切到生产项目)后,旧令牌没更新也会导致不匹配。客户端要监听令牌刷新事件,及时把最新令牌同步到服务端。
  • 细化错误日志:出现403时,额外记录当前用的项目ID(Projetos.getProjetoId的返回值),对比令牌对应的SenderId,确认是否真的不匹配,方便定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 20:03:13