Search code examples
google-mapsgeolocationgoogle-geolocation

Google Maps Geolocation API always returns 'Invalid JSON payload received.'


I am able to perform the below cURL operation provided by the Google Geolocation API docs.

example.json

{
    "considerIp": "false",
    "wifiAccessPoints": [
      {
          "macAddress": "00:25:9c:cf:1c:ac",
          "signalStrength": -43,
          "signalToNoiseRatio": 0
      },
      {
          "macAddress": "00:25:9c:cf:1c:ad",
          "signalStrength": -55,
          "signalToNoiseRatio": 0
      }
    ]
  }

Then I run the below in the terminal and get GPS coordinates.

$ curl -d @your_filename.json -H "Content-Type: application/json" -i "https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR_API_KEY"

However, when I try to execute this as a POST request using fetch, I get the below error.

{
  error: {
    code: 400,
    message: 'Invalid JSON payload received. Unexpected token.\n[object Object]\n ^',
    errors: [ [Object] ],
    status: 'INVALID_ARGUMENT'
  }
}

I have tried rewriting my options and request body different ways and have not found a solution. I have seen this answer but it doesn't really provide information regarding a fetch request. That question is referring to cell towers whereas I am working with wifiAccessPoints but I figured the structure of the request would be similar. Below is my request body, it's the same as example.json.

const body = {
        "considerIp": "false",
        "wifiAccessPoints": [
          {
              "macAddress": "00:25:9c:cf:1c:ac",
              "signalStrength": -43,
              "signalToNoiseRatio": 0
          },
          {
              "macAddress": "00:25:9c:cf:1c:ad",
              "signalStrength": -55,
              "signalToNoiseRatio": 0
          }
        ]
      }

And here is my POST fetch request.

var url = "https://www.googleapis.com/geolocation/v1/geolocate?key=" + apiKey
    fetch(url, {method: 'POST', headers: {
        'Content-Type': 'application/json'
        // 'Content-Type': 'application/x-www-form-urlencoded',
      }, body: body})
    .then(res=>res.json())
    .then((json,err)=>{
        if (err){
            console.log(err)
        } else {
           console.log(json)
        }
    })

My API key is valid an unrestricted (I also use it for the places API) and when I tried my key in the cURL op it returned the coordinates response.

Is it even possible to make a request to this API using fetch? I am open to other alternatives I just can't have it be a command line request.


Solution

  • You need to serialize the value of your body into a JSON string by using JSON.stringify(body). Here is the sample code and a sample fiddle (Note: replace the string YOUR_API_KEY with your own API key) .

    const body = {
            "considerIp": "false",
            "wifiAccessPoints": [
              {
                  "macAddress": "00:25:9c:cf:1c:ac",
                  "signalStrength": -43,
                  "signalToNoiseRatio": 0
              },
              {
                  "macAddress": "00:25:9c:cf:1c:ad",
                  "signalStrength": -55,
                  "signalToNoiseRatio": 0
              }
            ]
          }
    
    fetch("https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR_API_KEY", {
      method: "post",
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
    
      //make sure to serialize your JSON body
      body: JSON.stringify(body)
    })
    .then(res=>res.json())
        .then((json,err)=>{
            if (err){
                console.log(err)
            } else {
               console.log(json)
            }});
    

    Hope this helps!