Search code examples
google-fitgoogle-fit-api

REST API 400 Bad Request for Aggregated Activity Segments on Empty Data


We’re requesting activity data aggregated by segments for our users via REST interface. But for some users (not all), retrieving this data fails with a 400 Bad Request despite sharing the same request format.

An example request JSON to aggregate by segments is:

{
"aggregateBy": [
  {
    "dataTypeName": "com.google.activity.segment"
  },
  {
    "dataTypeName": "com.google.calories.expended"
  },
  {
    "dataTypeName": "com.google.step_count.delta"
  }
],
"bucketByActivitySegment": {
  "minDurationMillis": 60000
},
"startTimeMillis": 1627182120000,
"endTimeMillis": 1627268520000
}

For all users with recorded activity data, we receive successful responses with data points, like for example:

{
  "bucket": [
    {
      "startTimeMillis": "1627180684015",
      "endTimeMillis": "1627182139339",
      "dataset": [
        {
          "dataSourceId": "derived:com.google.activity.summary:com.google.android.gms:aggregated",
          "point": [
            {
              "startTimeNanos": "1627180684015000000",
              "endTimeNanos": "1627182139339000000",
              "dataTypeName": "com.google.activity.summary",
              "originDataSourceId": "derived:com.google.activity.segment:com.google.android.gms:merge_activity_segments",
              "value": [
                {
                  "intVal": 7,
                  "mapVal": []
                },
                {
                  "intVal": 1455324,
                  "mapVal": []
                },
                {
                  "intVal": 1,
                  "mapVal": []
                }
              ]
            }
          ]
        },
[...]

But for users with no recorded activity data, we always receive 400 Bad Request responses, like:

{
    "error": {
        "code": 400,
        "message": "unknown datasource: derived:com.google.activity.segment:com.google.android.gms:merge_activity_segments",
        "errors": [
            {
                "message": "unknown datasource: derived:com.google.activity.segment:com.google.android.gms:merge_activity_segments",
                "domain": "global",
                "reason": "invalidArgument"
            }
        ],
        "status": "INVALID_ARGUMENT"
    }
}

We confirmed that there is no recorded activity data by aggregating activity data by time, e.g. the request

{
"aggregateBy": [
  {
    "dataTypeName": "com.google.activity.segment"
  }
],
"bucketByTime": {
  "durationMillis": 60000
},
"startTimeMillis": 1627182120000,
"endTimeMillis": 1627268520000
}

leads to a successful response with completely empty data points, like:

{
    "bucket": [
        {
            "startTimeMillis": "1627182120000",
            "endTimeMillis": "1627182180000",
            "dataset": [
                {
                    "dataSourceId": "derived:com.google.activity.summary:com.google.android.gms:aggregated",
                    "point": []
                }
            ]
        },
[...]
            "dataset": [
                {
                    "dataSourceId": "derived:com.google.activity.summary:com.google.android.gms:aggregated",
                    "point": []
                }
            ]
        }
    ]
}

Our questions are:

  • Is the 400 Bad Request response actually avoidable for users with empty data?
  • Or should this be considered a bug in the Google Fit API? We don't see a reason to respond with a 400 Bad Request instead of empty data when aggregating empty data by segments.

Solution

  • It was confirmed to us by the Google Fit team that this response behavior is not going to change, as users might already rely on it. We need to work around this, e.g. handle this error response separately, check if data is empty or something like this.