Swift中HTTP POST请求FCM返回401错误求排查
排查Swift集成Firebase FCM推送401未授权问题
在Swift应用中集成Firebase FCM实现设备间推送时,遇到401未授权错误,同时伴随JSON解析失败提示。以下是相关代码、错误信息及排查修复方案:
问题代码
class PushNotificationSender { let key = NotificationConstants().key_2 func sendPushNotification(to token: String, title: String, body: String) { let urlString = "https://fcm.googleapis.com/fcm/send" let url = NSURL(string: urlString)! let paramString: [String : Any] = ["to" : token, "notification" : [ "body" : body, "title" : title, "sound" : true ] ] let request = NSMutableURLRequest(url: url as URL) request.httpMethod = "POST" request.httpBody = try? JSONSerialization.data(withJSONObject:paramString, options: [.prettyPrinted]) request.setValue("key=\(self.key)", forHTTPHeaderField: "Authorization") request.setValue("application/json", forHTTPHeaderField: "Content-Type") let task = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in do { if let jsonData = data { if let jsonDataDict = try JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions.allowFragments) as? [String: AnyObject] { NSLog("Received data:\n\(jsonDataDict))") } } } catch let err as NSError { print(err.debugDescription) print(error as Any) print(err ) print(response as Any) print(request) } } task.resume() print("Pushnotification Sent") } }
错误信息
Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around line 1, column 0." UserInfo={NSDebugDescription=Invalid value around line 1, column 0., NSJSONSerializationErrorIndex=0} Optional(<NSHTTPURLResponse: 0x2828da4c0> { URL: https://fcm.googleapis.com/fcm/send } { Status Code: 401, Headers { "Alt-Svc" = ( "h3=\"\:443\"; ma=2592000,h3-29=\"\:443\"; ma=2592000,h3-Q050=\"\:443\"; ma=2592000,h3-Q046=\"\:443\"; ma=2592000,h3-Q043=\"\:443\"; ma=2592000,quic=\"\:443\"; ma=2592000; v=\"46,43\"" ); "Cache-Control" = ( "private, max-age=0" ); "Content-Encoding" = ( gzip ); "Content-Length" = ( 130 ); "Content-Type" = ( "text/html; charset=UTF-8" ); Date = ( "Fri, 21 Oct 2022 16:55:01 GMT" ); Expires = ( "Fri, 21 Oct 2022 16:55:01 GMT" ); Server = ( GSE ); "content-security-policy" = ( "frame-ancestors 'self'" ); "x-content-type-options" = ( nosniff ); "x-frame-options" = ( SAMEORIGIN ); "x-xss-protection" = ( "1; mode=block" ); } })
当前Firebase配置
- 已启用Firebase Cloud Messaging API (V1)
- 已配置APNs认证密钥
排查与修复方案
- 确认服务器密钥正确性:当前使用的
key_2必须是Firebase控制台「项目设置 > 云消息传递」中的服务器密钥,而非V1 API的服务账号密钥或APNs密钥。旧版FCM端点fcm/send仅支持服务器密钥认证,V1 API需要OAuth2令牌,两者不能混用。 - 修正JSON字段格式:FCM的
sound字段要求为字符串类型(如"default"),而非布尔值true,这会导致JSON序列化异常,修改参数:let paramString: [String : Any] = ["to" : token, "notification" : [ "body" : body, "title" : title, "sound" : "default" ] ] - 捕获JSON序列化错误:原代码用
try?忽略了序列化异常,改为显式捕获确保格式正确:do { request.httpBody = try JSONSerialization.data(withJSONObject: paramString, options: []) } catch { print("JSON序列化失败:\(error)") return } - 验证Authorization头格式:确保
Authorization头严格为key=你的服务器密钥,密钥无换行、空格或截断,可直接在控制台复制完整密钥替换key_2测试。
内容的提问来源于stack exchange,提问作者deveca
相关产品推荐
相关产品推荐

