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

Android Studio调用FCM发送推送报401 AuthFailureError问题

FCM跨设备推送报AuthFailureError(401错误)原因与修复方案

你遇到的com.android.volley.AuthFailureError伴随接口返回401状态码,本质是调用FCM推送接口时未通过服务端鉴权,以下是具体诱因和对应解决方式:

核心产生原因

  • 请求头格式不规范:代码中鉴权头的键名写为全小写authorization,FCM接口对头字段大小写敏感,小写的鉴权头会被判定为未携带合法鉴权信息;同理Content-type写法也不符合HTTP标准头规范。
  • 服务端密钥配置错误:代码中引用的fcmServerKey不是合法的FCM Legacy服务端密钥,属于最高发的诱因,常见错误场景包括:
    • 误用客户端Web API Key:也就是google-services.json文件里的current_key字段,该密钥仅开放给客户端使用,没有推送发送权限
    • 误复制Firebase项目的APP ID、客户端SDK配置值等非服务端密钥
    • 复制密钥时夹带了多余的空格、换行符
    • 密钥已在Firebase控制台被重置,旧密钥自动失效
  • 接口与鉴权方式不匹配:代码中调用的是FCM Legacy版发送接口,如果误用了FCM V1版本的鉴权规则(V1需要OAuth2.0短期令牌,不支持key=xxx的拼接格式),也会直接返回401。
  • 服务权限未开通:Firebase项目的Cloud Messaging API处于未启用状态,对应密钥没有推送发送权限。

修复步骤

  1. 修正请求头写法,将头字段调整为HTTP标准大小写格式,鉴权头键名改为Authorization,内容类型头改为Content-Type。
  2. 核对正确的Legacy服务端密钥:
    • 打开对应Firebase项目的设置页面
    • 切换到「云消息传递」标签页
    • 在「Cloud Messaging API (Legacy)」板块,确认服务状态为已启用,再复制板块内显示的服务器密钥替换代码中的fcmServerKey,不要使用其他位置的密钥值。
  3. 如果已经迁移到FCM V1版本接口,不要继续使用Legacy的key=xxx鉴权方式,要么换回Legacy接口地址匹配Legacy密钥,要么按照V1规范生成OAuth2.0访问令牌做鉴权。
  4. 安全风险修复:不要在安卓客户端代码里硬编码FCM服务端密钥、直接从客户端调用FCM发送接口,客户端代码很容易被反编译导致密钥泄露,恶意人员拿到密钥可以向你的所有应用用户推送垃圾消息。正确实现逻辑是把推送发送逻辑部署到你自己的业务服务端,客户端只负责把设备推送Token上报给你的服务端,由服务端调用FCM接口完成推送下发。

修正后的参考代码

public static void SendNotifications(Context applicationContext, String targetToken, String title, String body) {
    // 注意:客户端直接调用FCM发送接口存在严重密钥泄露风险,仅做临时调试使用
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
    RequestQueue queue = Volley.newRequestQueue(applicationContext);
    try {
        JSONObject json = new JSONObject();
        json.put("to", targetToken);
        JSONObject notification = new JSONObject();
        notification.put("title", title);
        notification.put("body", body);
        json.put("notification", notification);
        // Legacy版FCM发送接口地址
        String postUrl = "https://fcm.googleapis.com/fcm/send";
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, postUrl, json,
                response -> Log.e("Result", String.valueOf(response)),
                error -> Log.e("Result", String.valueOf(error))
        ) {
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> header = new HashMap<>();
                // 修正头字段为标准格式
                header.put("Content-Type", "application/json");
                header.put("Authorization", "key=" + fcmServerKey);
                return header;
            }
        };
        queue.add(jsonObjectRequest);
    } catch (JSONException jsonException) {
        jsonException.printStackTrace();
    }
}

调试技巧:如果修正代码后依然返回401,可以先把密钥和请求参数放到接口调试工具中直接调用FCM接口测试,如果工具请求也返回401,说明问题和代码逻辑无关,直接排查密钥有效性和项目服务开通状态即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 03:42:31