Search code examples
google-fit

Pagination yields no results in Google Fit


I am using the REST API of Google Fit. I want to list sessions with the fitness.users.sessions.list method. This gives me a few dozen of results.

Now I would like to get more results and for this I set the pageToken to the value I got from the previous response. But the new results does not contain any data points, just yet another pageToken:

{
 "session": [
 ],
 "deletedSession": [
 ],
 "nextPageToken": "1541027616563"
}

The same happens when I use the pagination function of the Google Python API Client: I iterate on results but never get any new data.

    request = self.service.users().sessions().list(userId='me')
    while request is not None:
        response = request.execute()
        for ds in response['session']:
            yield ds
        request = self.service.users().sessions().list_next(request, response)

I am sure there is much(!) more session data in Google Fit for my account. Am I missing something regarding pagination?

Thanks


Solution

  • I think that the description of the pageToken parameter is actually rather confusing in the documentation (this answer was written prior to the documentation being updated).

    The continuation token, which is used to page through large result sets. To get the next page of results, set this parameter to the value of nextPageToken from the previous response.

    This is conflating two concepts: continuation, and paging. There isn't actually any paging in the implementation of Users.sessions.

    Sessions are indexed by their modification timestamp. There are two (or three, depending on how you count) ways to interact with the API:

    • Pass a start and/or end time. Omitted start and end times are taken to be the start and end of time respectively. In this case, you will get back all sessions falling between those times.
    • Pass neither start nor end times. In this case, you will receive all sessions between some time in the past and now. That time is:
      • pageToken, if provided
      • Otherwise, it's 7 days ago (this doesn't actually appear in the documentation, but it is the behavior)

    In any of these cases, you receive a nextPageToken back which is just after the most recent session in the results. As such, nextPageToken is really a continuation token, because what it is saying is that you have been told about all sessions modified up to now: pass that token back to be told about anything modified between nextPageToken and "current time" to get updates.

    As such, if you issue a request that fetches all sessions for the last 7 days (no start/end time, no page token) and get a nextPageToken, you will only get something back in a request using that nextPageToken if any sessions have been modified in between the first and second requests.

    So, if you're making these requests in quick succession, it is expected that you won't see anything in the second response.


    In terms of the validity of the startTime you were passing in your comment, that's a bug. RFC3339 defines that fractional seconds should be optional.

    I'll see about getting that fixed; but in the interim, just make sure you pass a fractional number of seconds (even if it is just .0, e.g. 2018-10-18T00:00:00.0+00:00).