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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 22:15:51