【问题标题】:still having trouble with my FCM http request我的 FCM http 请求仍然有问题
【发布时间】:2021-03-04 00:07:48
【问题描述】:

我只是希望能够向订阅了某个主题的用户发送没有错误的通知。

这是我用来实现这个目标的函数:

 func sendNotificationToUser(to topic: String, title: String, body: String) {
   
    let urlString = "https://fcm.googleapis.com/v1/projects/projectname-41f12/messages:send HTTP/1.1"
    guard let encodedURLString = urlString.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed) else { return }
    let url = URL(string: encodedURLString)!
    
    struct PostBody: Codable {
        struct Message: Codable {
            let topic: String
            let notification: [[String: String]]
        }
        let message: Message
    }
    
    let postBody = PostBody(message: PostBody.Message(topic: topic,
                                                      notification: [
                                                        ["title": title],
                                                        ["body": body]
                                                                                ]))
    
    
   let encoder = JSONEncoder()
    encoder.outputFormatting = .prettyPrinted
    
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.httpBody = try? encoder.encode(postBody)
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.setValue("Bearer ya29.\(self.bearer)", forHTTPHeaderField: "Authorization")
    let task = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in
        do {
            if let jsonData = data {
                if let jsonDataDictionary = try JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions.allowFragments) as? [String: AnyObject] {
                    NSLog("Received data:\n\(jsonDataDictionary))")
                }
                
            }
        } catch let err as NSError {
            print(err)
            print(postBody.message)
            
        }
    }
    task.resume()
}

这是我按下按钮后调用它的函数:

 getTheSchoolID { (id) in
            if let id = id {
                self.sendNotificationToUser(to: id, title: "New Event Added!", body: "A new event has been added to the dashboard!!")

            }
        }

当我按下按钮时,我不断收到一个 NSCocoaError 并且我仍然这样做,所以我做了我的研究并将我的 JSON 通过 jsonlint.com 并通过简单地将括号更改为大括号并在周围添加双引号来验证它对象。现在,当我在 Swift 中运行它时,会出现如下错误:

JSON数据打印在错误中间,我看不到JSON有什么问题,我的http请求有问题吗?

编辑我想要的 JSON 结构:

【问题讨论】:

    标签: json swift http-headers firebase-cloud-messaging nsdictionary


    【解决方案1】:

    JSON 无效 - 您将字典和数组混为一谈,这种方式不适用于大多数工具。您需要将您的 dicts 嵌入到 {...} 中。以下修改(扩展/缩进到最大以显示结构)有效,据我所知是相同的结构:

    {
      "message": [
        {
          "topic": "23452345234"
        },
        {
          "notification": [
            {
              "body": "messsage"
            },
            {
              "title": "new event"
            }
          ]
        }
      ]
    }
    

    如果出于某种原因您想要一个数组而不是字典,则将上述所有内容嵌入方括号中以获得单个项目数组。

    但是我可能会使用临时结构来生成主体,然后依靠Encodable 为我完成工作。下面是一个粗略的解决方案(有很多事情可以改进 - 不是硬编码 dict 键,传入一个形成的 dict,正确处理来自编码器的错误等,......)但希望这会让你开始。

    func sendNotificationToUser(to topic: String, title: String, body: String) {
       
       struct PostBody: Codable {
          struct Message: Codable {
             let topic: String
             let notification: [String: String]
          }
          let message: Message
       }
    
       // generate the request...
    
       let postBody = PostBody(message: PostBody.Message(
                                  topic: topic,
                                  notification: [
                                     "title": title,
                                     "body": body ]
                                  ) 
                                 )
       
       let encoder = JSONEncoder()
       encoder.outputFormatting = .prettyPrinted
       request.httpBody = try? encoder.encode(postBody)
    
       // finish request, completion handler, etc, etc
    }
    

    生成的 JSON 是

    {
      "message" : {
        "topic" : "topictext",
        "notification" : {
          "title" : "titleText",
          "body" : "bodyText"
        }
      }
    }
    

    【讨论】:

    • 好的,我怎样才能在我上面发布的 Swift http 函数中做到这一点?我可以在paramString 变量中使用这些括号吗?我将添加我想要的确切 json 结构的图像。 @侧翼
    • @dsonawave 编辑的答案为您提供了一个基本的起点
    • 我最初根据错误消息对 json 结构的猜测是不正确的(由于括号四处喷洒)。我的`实际输出与您的结构非常相似,但通知值在一个数组中......因为它们是一个dict数组。
    • 是的,我不认识。如果不是“字符 0 周围的值无效”,我仍然会遇到相同的错误。然后是“没有价值”。 @侧翼
    • 因此,上述 Firebase 文档中图像中的结构与您现在向我展示的 JSON 结构完全相同。正确的? @侧翼
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    相关资源
    最近更新 更多