在Firebase数据库和Swift中使用POST和Auth

问题描述

我需要在iOS应用上使用REST Api从服务器发布/检索数据。该应用程序设置有密钥生成器,该密钥生成器为我获取了ID令牌,然后使用ID格式化我的http请求。我知道有关我的url请求的某些信息是错误的,我只是不知道是什么,但是每当我运行此命令时,我都会获得状态码400。有什么想法我做错了吗?

    func postToFB() {
        
        let preURL = "https://myapp.firebaseio.com/"
        let url = URL(string: "\(preURL)\(code)/calculatordisplay.json?auth=\(idToken)")!
        var request = URLRequest(url: url)
        request.setValue("application/json",forHTTPHeaderField: "Content-Type")
        request.httpMethod = "PUT"
        let parameters: [String: Any] = [
            "field1": env.field1,"field2": env.field2
        ]
        request.httpBody = parameters.percentEncoded()
        
        let task = URLSession.shared.dataTask(with: request) { data,response,error in
            guard let data = data,let response = response as? HTTPURLResponse,error == nil else {                                              // check for fundamental networking error
                print("postCalcDataButtons error",error ?? "UnkNown error")
                return
            }
            
            guard (200 ... 299) ~= response.statusCode else {                    // check for http errors
                print("postCalcDataButtons = statusCode should be 2xx,but is \(response.statusCode)")
                print("postCalcDataButtons response = \(response)")
                return
            }
            
            let responseString = String(data: data,encoding: .utf8)
            print("postCalcDataButtons responseString = \(String(describing: responseString))")
        }
        
        task.resume()
    }

以下是使上述代码起作用的扩展名:

extension Dictionary {
    func percentEncoded() -> Data? {
        return map { key,value in
            let escapedKey = "\(key)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
            let escapedValue = "\(value)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
            return escapedKey + "=" + escapedValue
        }
        .joined(separator: "&")
        .data(using: .utf8)
    }
}

extension CharacterSet {
    static let urlQueryValueAllowed: CharacterSet = {
        let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
        let subDelimitersToEncode = "!$&'()*+,;="
        
        var allowed = CharacterSet.urlQueryAllowed
        allowed.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)")
        return allowed
    }()
}

这是服务器的响应:

<NSHTTPURLResponse: 0x60000110a0a0> { URL: https://calculonapp.firebaseio.com/zlwxrx/calculatorButtons.json?auth=authCode } { Status Code: 400,Headers {
    "Access-Control-Allow-Origin" =     (
        "*"
    );
    "Cache-Control" =     (
        "no-cache"
    );
    Connection =     (
        "keep-alive"
    );
    "Content-Length" =     (
        77
    );
    "Content-Type" =     (
        "application/json; charset=utf-8"
    );
    Date =     (
        "Fri,21 Aug 2020 21:16:43 GMT"
    );
    Server =     (
        Nginx
    );
    "Strict-Transport-Security" =     (
        "max-age=31556926; includeSubDomains; preload"
    );
} }

解决方法

我能够通过以下方式解决此问题:在将数据写入Firebase时将http方法更改为“ PATCH”,然后在运行URLSession之前添加JSONSerialization以编码我的上载...这是我使用的代码:

Pima_training['type'] = Pima_training['type'].replace({"No":0,"Yes":1})

在测试捕获http错误代码并将其报告给您时,您可以保留在警卫声明中,但是一旦我的代码起作用,我便将其删除。