我正在尝试测试 Firebase Cloud 消息 API,因为控制台无法提供所有功能(特别是应用程序在后台时的通知自定义)。但由于某些原因,我无法让它工作,并且总是显示 401 错误。我调查了原因,并在重新生成新的服务器密钥后进行了尝试,但错误仍然存在。令人惊讶的是,当我生成新的服务器密钥时,它没有反映在 Firebase 控制台中,并且将服务器密钥显示为空。另外,我尝试将我的 IP 地址添加到服务器白名单 IP,但仍然没有成功。我附上了我使用 Postman 执行的请求的屏幕截图(我用服务器密钥代替了 serverKey。
我不知道是否有人使用[Web API Key]作为[YOUR_SERVER_KEY]进行POSTMAN测试并不断收到“401错误”。 [Web API 密钥] 不是 [YOUR_SERVER_KEY]。
您应该转到 Firebase 控制台并检查以下内容:
获取正确的服务器密钥。
希望有帮助。
我从您的屏幕截图中注意到您正在使用“key:serverKey”。您可以尝试使用“key=serverKey”来代替吗?
您也不需要“POST fcm.googleapus.com/fcm/send”;这不是正确的 json,可以解释您所看到的错误。请求的 URL 已在其他地方定义,因此请将其从有效负载中删除。
我也遇到了同样的问题。
问题是我使用的是旧服务器密钥。当我使用新版本的服务器密钥时,问题解决了。
在 Firebase 控制台中转到设置 -> 云消息
然后使用新的服务器密钥。它比旧版本密钥更长。
转到 https://console.firebase.google.com/u/0/project/[项目名称]/settings/cloudmessaging/
您可以使用服务器密钥或旧服务器密钥
我也面临着同样的问题...我在 php 中使用curl 进行发布,并且只有当我的 LocalHost 服务器上存储有 php 文件时它才有效。当我尝试通过免费在线托管访问文件时,它显示未经授权 401。
所以我建议如果可以的话,使用本地主机。
如果您通过 HTTP v1 使用 FCM,那么您将必须发出两个连续的 POST 请求:
1/ 在第一次通话中,您向 发出 POST
请求https://accounts.google.com/o/oauth2/token
(或使用 API 包)使用您的 Firebase 服务帐户密钥
https://console.firebase.google.com/u/0/project/{{firebaseProjectName}}/settings/serviceaccounts/adminsdk
获取访问令牌。如果异步,请等待响应。
2/ 然后你必须向发出另一个POST
请求https://fcm.googleapis.com/v1/projects/{{firebaseProjectName}}/messages:send
如果您已按照 Firebase 网站上从旧版 HTTP 迁移到 HTTP v1 的步骤(非常清晰的文档)进行操作,则必须对 post 请求的内容进行一些小更改,并使用“Bearer ${accessToken.data}” ' 以获得授权。
就我而言,我没有在第一个函数中正确等待 accessToken(忘记了发出 post 请求的函数前面的“await”关键字,AndroidStudio 也没有注意到有问题)。
确保等待第一个发布请求的结果,因为它是 Future。
如果不这样做,当您发出第二个 POST 请求时,Bearer 将为 null,因为您没有等待它。
我在服务器端代码(C#)也有同样的问题。
您基本上使用了错误的服务器密钥(或 API 密钥)作为服务端代码。
按照我发布的 stackoverflow 上的链接进行操作(有助于查找服务器密钥(或 API 密钥))
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();
}
}
}
在 C# HttpClient 响应中
如果服务器密钥错误,会发生无效密钥、未授权、401
我遇到了同样的问题,我通过以下步骤解决了它
1-在发送推送的服务器中,仅使用浏览器密钥,您可以从 Firebase 控制台或 google api 控制台获取它,如下图所示:-
注意:Firebase 控制台 Web api 密钥和 google 控制台浏览器密钥相同,您可以使用其中任何一个
2-如果您仅按照第一步操作,您将收到未经授权的错误,要解决此问题,您需要通过添加您将发送推送的服务器 IP 地址,在 google 控制台中授权您的浏览器密钥。单击 google api 控制台中浏览器键右侧的编辑铅笔图标(第一张图片上方)
添加您的 IP 地址后单击“保存” 确保您发送推送的设备令牌不为空,我希望您的推送现在能够成功发送。