- Home /
Why do I get Parse error (code 400) from Google Ftiness API in Unity?
I am trying to read steps count from GoogleFitness API in Unity application. First I go to Google's OAuthPlayground, authorize the fitness api and copy the access token. In Unity I have a scene with text field and a button. I paste the access token to the textfield and click the button. On Button click the method GetStepsResponse is being called with input field's content as a param.
The logic behind:
public void GetStepsResponse(string idToken)
{
StartCoroutine(SendPostCoroutine(idToken));
}
IEnumerator SendPostCoroutine(string accessToken)
{
string request = "https://www.googleapis.com/fitness/v1/users/me/dataset:aggregate";
request = string.Concat(request, "?access_token=", accessToken);
string body = "{ \"aggregateBy\": [{ \"dataTypeName\": \"com.google.step_count.delta\", \"dataSourceId\": \"derived:com.google.step_count.delta:com.google.android.gms:estimated_steps\" }], \"bucketByTime\": { \"durationMillis\": 86400000 }, // This is 24 hours \"startTimeMillis\": 1577059200000, //start time \"endTimeMillis\": 1577577600000// End Time}";
UnityWebRequest webRequest = UnityWebRequest.Post(request, body);
webRequest.SetRequestHeader("Content-type", "application/json");
yield return webRequest.SendWebRequest();
Debug.Log(webRequest.downloadHandler.text);
}
as a response I get:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "parseError",
"message": "Parse Error"
}
],
"code": 400,
"message": "Parse Error"
}
}
I tried the same request with same body and headers here: https://apitester.com/ and I got a proper response with steps count for every day from given range. What I am missing?
EDIT
I came up with an idea that escaping the quatiion mark in the request body may cause the Parse Error, so I switched from manually constructing a request body string to serializing an object to JSON and using the product string as a body:
public void GetStepsResponse(string idToken)
{
StartCoroutine(SendPostCoroutine(idToken));
}
IEnumerator SendPostCoroutine(string accessToken)
{
string request = "https://www.googleapis.com/fitness/v1/users/me/dataset:aggregate";
request = string.Concat(request, "?access_token=", accessToken);
FitnessRequest requestBody = new FitnessRequest();
requestBody.aggregateBy = new AggregateByRequestParam[1];
requestBody.aggregateBy[0] = new AggregateByRequestParam();
requestBody.aggregateBy[0].dataTypeName = "com.google.step_count.delta";
requestBody.aggregateBy[0].dataSourceId = "derived:com.google.step_count.delta:com.google.android.gms:estimated_steps";
requestBody.bucketByTime = new DurationRequestParam();
requestBody.bucketByTime.durationMillis = 86400000;
requestBody.startTimeMillis = 1577059200000;
requestBody.endTimeMillis = 1577577600000;
string body = JsonUtility.ToJson(requestBody);
Debug.Log(body);
UnityWebRequest webRequest = UnityWebRequest.Post(request, body);
webRequest.SetRequestHeader("Content-type", "application/json");
yield return webRequest.SendWebRequest();
Debug.Log(webRequest.downloadHandler.text);
}
[System.Serializable]
private class FitnessRequest
{
public AggregateByRequestParam[] aggregateBy;
public DurationRequestParam bucketByTime;
public long startTimeMillis;
public long endTimeMillis;
}
[System.Serializable]
private class AggregateByRequestParam
{
public string dataTypeName;
public string dataSourceId;
}
[System.Serializable]
private class DurationRequestParam
{
public long durationMillis;
}
However the result is still the same. Again, when I use the same request url and request body outside Unity it works (I get code 200 as a response). Is there something specific in Unity's UnityWebRequest.Post that I'm missing?
Your answer
Follow this Question
Related Questions
Get data from REST works on Unity but not on Android Device 1 Answer
Try catch alternative for HTTP request 1 Answer
HTTP PUT in Unity for iOS? 2 Answers
Google text-to-speech via HTTP 7 Answers