Home > Back-end >  How to run structured query using Alamofire?
How to run structured query using Alamofire?

Time:05-25

As you can see in the image below, It works well in PostMan.

PostMan

But, my code didn't work...

func getMy() {
    let projectId = "lolcourt-554c8"
    let url = "https://firestore.googleapis.com/v1/projects/\(projectId)/databases/(default)/documents:runQuery"
    var request = URLRequest(url: URL(string: url)!)
    request.httpMethod = "POST"
    do {
        let post = MyPost(userId: "Mr.Kim")
        request.httpBody = try JSONEncoder().encode(post)
    } catch {
        print("http Body Error")
    }
    AF.request(request).responseString { response in
        print(response)
    }

Output:

success("[{\n  \"error\": {\n    \"code\": 400,\n    \"message\": \"Invalid JSON payload received. Unknown name \\\"{\\\"structuredQuery\\\":{\\\"where\\\":{\\\"fieldFilter\\\":{\\\"field\\\":{\\\"fieldPath\\\":\\\"userID\\\"},\\\"op\\\":\\\"EQUAL\\\",\\\"value\\\":{\\\"stringValue\\\":\\\"Mr.Kim\\\"}}},\\\"orderBy\\\":[{\\\"field\\\":{\\\"fieldPath\\\":\\\"date\\\"},\\\"direction\\\":\\\"DESCENDING\\\"}],\\\"from\\\":[{\\\"collectionId\\\":\\\"lolCourt\\\"}]}}\\\": Cannot bind query parameter. Field \'{\\\"structuredQuery\\\":{\\\"where\\\":{\\\"fieldFilter\\\":{\\\"field\\\":{\\\"fieldPath\\\":\\\"userID\\\"},\\\"op\\\":\\\"EQUAL\\\",\\\"value\\\":{\\\"stringValue\\\":\\\"Mr\' could not be found in request message.\",\n    \"status\": \"INVALID_ARGUMENT\",\n    \"details\": [\n      {\n        \"@type\": \"type.googleapis.com/google.rpc.BadRequest\",\n        \"fieldViolations\": [\n          {\n            \"description\": \"Invalid JSON payload received. Unknown name \\\"{\\\"structuredQuery\\\":{\\\"where\\\":{\\\"fieldFilter\\\":{\\\"field\\\":{\\\"fieldPath\\\":\\\"userID\\\"},\\\"op\\\":\\\"EQUAL\\\",\\\"value\\\":{\\\"stringValue\\\":\\\"Mr.Kim\\\"}}},\\\"orderBy\\\":[{\\\"field\\\":{\\\"fieldPath\\\":\\\"date\\\"},\\\"direction\\\":\\\"DESCENDING\\\"}],\\\"from\\\":[{\\\"collectionId\\\":\\\"lolCourt\\\"}]}}\\\": Cannot bind query parameter. Field \'{\\\"structuredQuery\\\":{\\\"where\\\":{\\\"fieldFilter\\\":{\\\"field\\\":{\\\"fieldPath\\\":\\\"userID\\\"},\\\"op\\\":\\\"EQUAL\\\",\\\"value\\\":{\\\"stringValue\\\":\\\"Mr\' could not be found in request message.\"\n          }\n        ]\n      }\n    ]\n  }\n}\n]")

I think the encoding was completed without any errors.

if let encoded = try? JSONEncoder().encode(MyPost(userId: "Mr.Kim")) {
        print(String(data: encoded, encoding: .utf8)!)
    }

Output:

{"structuredQuery":{"where":{"fieldFilter":{"field":{"fieldPath":"userID"},"op":"EQUAL","value":{"stringValue":"Mr.Kim"}}},"orderBy":[{"field":{"fieldPath":"date"},"direction":"DESCENDING"}],"from":[{"collectionId":"lolCourt"}]}}

CodePudding user response:

This related to parameter encoding , simply add this header

request.addValue("application/json", forHTTPHeaderField: "Content-Type")

CodePudding user response:

There's no need to do you own parameter encoding, Alamofire has that built in.

AF.request(url: ..., method: .post, parameters: post, encoder: JSONParameterEncoder.default)

This will properly encode any Encodable type as JSON.

PS. To print response JSON without escaping I recommend print(String(decoding: data, as: UTF8.self) as NSString)

  • Related