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 控制台获取它在下图中突出显示:-
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
我正在尝试测试 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 控制台获取它在下图中突出显示:-
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