Firebase 401 未经授权的错误 FCM

Firebase 401 unauthorized error FCM

我正在尝试测试 Firebase 云消息传递 API,因为控制台无法提供所有功能(尤其是当应用程序在后台时自定义通知)。但是由于某些原因,我无法让它工作,而且它总是显示 401 错误。查了原因,重新生成新的server key后试了一下,还是报错。令人惊讶的是,当我生成一个新的服务器密钥时,它并没有反映在 Firebase 控制台中,而是将服务器密钥显示为空。此外,我尝试将我的 IP 地址添加到服务器白名单 IP,但仍然没有成功。我附上了我对 Postman 所做的请求的屏幕截图(我用服务器密钥代替了 serverKey

我在这上面停留了几个小时,非常感谢您的帮助。

我从你的屏幕截图中注意到你正在使用 "key: serverKey"。您可以尝试改用 "key=serverKey" 吗?

你也不需要 "POST fcm.googleapus.com/fcm/send";这是不正确的 json 并且可以解释您看到的错误。请求的 URL 已在别处定义,因此请将其从负载中删除。

我也面临同样的问题...我在 php 中使用 curl 进行发布,只有当我的 LocalHost 服务器上存储了 php 文件时它才有效。当我尝试通过免费在线托管访问文件时,它显示未自动 401。

因此,如果可以的话,我建议您使用 Localhost。

我在服务器端代码 (C#) 中遇到了同样的问题。

您基本上为服务端代码使用了错误的服务器密钥(或 API 密钥)。

在我发布的 Whosebug 上关注 Link(有助于找到服务器密钥(或 API 密钥))

我遇到了同样的问题,我通过以下步骤解决了它

1- 在您发送推送的服务器中,仅使用浏览器密钥,您可以像我一样从 Firebase 控制台或 google api 控制台获取它在下图中突出显示:-

Google api console

Firebase console, click on the project-->settings

注意:Firebase 控制台 Web api 密钥和 google 控制台浏览器密钥相同,您可以使用其中任何一个

2- 如果您只执行第一步,您将收到未经授权的错误,要解决此问题,您需要在 google 控制台中通过添加您的服务器 IP 地址来授权您的浏览器密钥您将在哪里发送推送。单击 google api 控制台中浏览器键右侧的编辑铅笔图标,第一张图片上方

添加您的 IP 地址后点击保存 请确保您发送推送的设备令牌不为空,希望您的推送现在能够成功发送。

我不知道是否有人将 [Web API Key] 用作 POSTMAN 测试的 [YOUR_SERVER_KEY] 并不断收到“401 错误”。 [Web API 密钥] 不是 [YOUR_SERVER_KEY]。

你应该去你的 Firebase 控制台检查一下:

获取正确的服务器密钥。

希望对您有所帮助。

我遇到了同样的问题。

问题是我使用的是旧版服务器密钥。当我使用新版本的服务器密钥时,问题就解决了。

在您的 firebase 控制台中转到设置 -> 云消息

然后使用新的服务器密钥。它比旧版本密钥长。

转到https://console.firebase.google.com/u/0/project/[project-name]/settings/cloudmessaging/

您可以使用服务器密钥或旧版服务器密钥

通过 HTTPv1 使用 FCM 的 401(Bearer 的错误和解决方案)

如果您正在使用 FCM via HTTP v1,那么您将必须连续发出两次 POST 请求:

1/ 在第一次调用中,您使用您的 firebase 服务帐户密钥向 'https://accounts.google.com/o/oauth2/token' 发出 POST 请求(或使用 API 包) 'https://console.firebase.google.com/u/0/project/{{firebaseProjectName}}/settings/serviceaccounts/adminsdk'
获取访问令牌。

2/ 然后你必须向 'https://fcm.googleapis.com/v1/projects/{{firebaseProjectName}}/messages:send' 发出另一个 POST 请求。如果您已按照 firebase 网站上从旧版 HTTP 迁移到 HTTP v1(非常清晰的文档)的步骤进行操作,则必须对 post 请求的内容进行一些小的更改,并使用 'Bearer ${accessToken.data}'获得授权。

在我的例子中,我没有正确等待第一个函数中的 accessToken(忘记了发出 post 请求的函数前面的 'await' 关键字,AndroidStudio 也没有注意到那里出了点问题)。

确保等待第一个 post 请求的结果,因为它是 Future。

如果不这样做,当您发出第二个 POST 请求时 Bearer 将为空,因为您没有等待它。

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.Size;

public class PushNotificationSubmit {

    public static void main(String[] args) {
        new PushNotificationSubmit().send("sample message title", "sample message body");
    }

    final String serverKey = "AAAA_*******";
    final String fcmUrl = "https://fcm.googleapis.com/fcm/send";

    /**
     * note from google: The value should be an array of registration tokens to which to send the multicast message. The array must contain at least 1 and at most 1000 registration tokens.
     * send to specific users
     *
     * @param messageTitle
     * @param messageBody
     * @param tokenList
     */
    @Size.List({@Size(min = 1), @Size(max = 999)})
    public void send(String messageTitle, String messageBody, List<String> tokenList) {
        try {
            String payloadJson = createMessageAsJson(messageTitle, messageBody, tokenList);
            doSend(payloadJson);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * send to all users that registered in my topic
     *
     * @param messageTitle
     * @param messageBody
     */
    public void send(String messageTitle, String messageBody) {
        try {
            String payloadJson = createMessageAsJson(messageTitle, messageBody, null);
            doSend(payloadJson);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private String createMessageAsJson(String messageTitle, String messageBody, List<String> tokenList) {
        JSONObject payloadObj = new JSONObject();
        try {
            JSONObject notifyObj = new JSONObject();
            notifyObj.put("title", messageTitle);
            notifyObj.put("body", messageBody);
            payloadObj.put("notification", notifyObj);

            if (tokenList != null) {
                if (tokenList != null && tokenList.size() > 0) {
                    JSONArray regId = new JSONArray();
                    for (int i = 0; i < tokenList.size(); i++) {
                        regId.put(tokenList.get(i));
                    }
                    payloadObj.put("registration_ids", regId);
                }
            } else {
                payloadObj.put("to", "/topics/all");
            }

            return payloadObj.toString();
        } catch (Exception e) {
            // TODO: add logger
            e.printStackTrace();
            throw e;
        }
    }

    private void doSend(String payloadJson) throws Exception {
        HttpClient httpclient = HttpClientBuilder.create().build();
        try {
            HttpPost httpPost = new HttpPost(fcmUrl);
            httpPost.setHeader("Content-Type", "application/json");
            httpPost.setHeader("Authorization", "key=" + serverKey);
            httpPost.setEntity(new StringEntity(payloadJson, "UTF-8"));

            HttpResponse response = httpclient.execute(httpPost);
            HttpEntity entity = response.getEntity();

            System.out.println("push notification status: " + response.getStatusLine());
            EntityUtils.consume(entity);
        } finally {
            httpclient.getConnectionManager().shutdown();
        }
    }
}

In C# HttpClient response

对于错误的服务器密钥会发生,无效密钥,未授权,401