0

So I am reasonably new to using API's with Js but I am struggling a lot to understand how the Google Fit API works. I am attempting to add a new Workout's data to the API by adding a session and some data for the intensity (heart points) of the session. I can get the session to appear correctly but run into constant errors when I try to create a dataSource and add a point to it for the session. It would be greatly appreciated if someone could help me to fix my code to achieve this or could direct me to a more thorough example of similar code as the API docs don't seem to be too well detailed with examples etc. Thanks in advance.

Here's the 3 api calls that I have written so far, one for creating the DataSource, one for the DataPoint and one for the Session. The session works correctly and adds a session of 1 hr for the correct activity but I am unable to get any of the other API requests to work.

Data Source :

``gapi.client.fitness.users.dataSources.create({
             "userId":"me",
             "resource": {
                "application": {
                "name": "LittleWorkouts"
              },
              "dataType": {"field":[{
                "format": "floatPoint",
                "name": "com.google.heart_minutes"
              }],


                "name": "com.google.heart_minutes"
              },
              "device": {
                "manufacturer": "op",
                "model": "6",
                "type": "phone",
                "uid": "1000019",
                "version": "1"
              },
              "type": "raw"
             }
         })
        .then(function(response) {
                // Handle the results here (response.result has the parsed body).
                console.log("Response", response);
              },
              function(err) { console.error("Execute error 1", err); });
``

Data Point :

``
    gapi.client.fitness.users.dataSources.datasets.patch({
      "dataSourceId":"raw:com.google.heart_minutes:292824132082:op:6:1000019",
      "userId": "me",
      "datasetId": "1592087806561000000-1592287806561000000",
      "resource": {
  "minStartTimeNs": "1592087806561000000",
  "maxEndTimeNs": "1592287806561000000",
  "dataSourceId": "raw:com.google.heart_minutes:292824132082:op:6:1000019",
  "point": [
    {
      "startTimeNanos": "1592087806561000000",
      "endTimeNanos": "1592287806561000000",
      "value": [
        {
          "fpVal": 89.1
        }
      ],
      "dataTypeName": "com.google.heart_minutes"
    }
  ]
}
    })
        .then(function(response) {
                // Handle the results here (response.result has the parsed body).
                console.log("Response", response);
              },
              function(err) { console.error("Execute error 2", err); });
``

Session :

``gapi.client.fitness.users.sessions.update({
            "userId":"me",
            "sessionId": "someSessionId19",
            "id": "someSessionId19",
            "name": "Awesome Workout19",
            "description": "A very intense workout",
            "startTimeMillis": new Date().getTime() - 3600000,
            "endTimeMillis": new Date().getTime(),
            "version": 1,
            "lastModifiedToken": "exampleToken",
            "application": {
                "detailsUrl": "http://example.com",
                "name": "LittleWorkouts",
                "version": "1.0"
            },
            "activityType": 21,
            "activeTimeMillis": 3600000
            }).then((res) => {console.log(res)});
            console.log('res')
        //request.execute((res) => {console.log(res);console.log('executrd')})


        console.log(auth2.currentUser.get().getBasicProfile().getGivenName());

        var request2 = gapi.client.fitness.users.sessions.list({
            "userId":"me"
        }).then((res) => {console.log(res)})
``

Error message

{message: "Unable to fetch DataSource for Dataset: raw:com.google.heart_minutes:292824132082:op:6:1000019", domain: "global", reason: "invalidArgument"}

Ben Cooper
  • 35
  • 8
  • Please define **unable to get any of the other API requests to work.** – Linda Lawton - DaImTo Jun 16 '20 at 08:30
  • @DaImTo well I get this for the DataSource request: message: "Invalid DataType: data_stream_id: "raw:com.google.heart_minutes:108881196053:op:6:1000019"↵type: RAWdata_type {name: "com.google.heart_minutes"field {name: "com.google.heart_minutes"format: FLOAT_POINTdevice uid: "1000019"type: PHONEversion: "1"model: "6" manufacturer: "op"application owner_console_id: 108881196053name: "LittleWorkouts" status: "INVALID_ARGUMENT" and this for the DataPoint: message: "Unable to fetch DataSource for Dataset: raw:com.google.heart_minutes:292824132082:op:6:1000019" status: "INVALID_ARGUMENT" – Ben Cooper Jun 16 '20 at 10:37
  • This API is really meant for use with mobile devices. Are you really trying to use it with javascript? Everythings designed around the data coming from a phone or watch. Not sure i want to ask but what exactly is your intention with this someone is going to log onto a website and click a link that they have started a workout then click again when they are done? – Linda Lawton - DaImTo Jun 16 '20 at 11:26
  • @DaImTo Yes, the idea was to have the user complete a workout and then the length of the workout and workout type would be recorded into google fit, my apologies if this was not the intended use of the API, it would not be possible at all? Thanks a lot for the response I appreciate it :) – Ben Cooper Jun 16 '20 at 12:59
  • Can you reformat the error message so it's in the format of the response? It's hard to pick it apart at the moment. – Andy Turner Jun 16 '20 at 16:15

2 Answers2

1

It looks like it could be that you're trying to pass in the wrong fields for the data type: if you want to use a standard data type (like com.google.heart_minutes), you should either pass the exact fields of the standard data type (the field should be called "intensity"); or just pass the data type name, and the backend will fill them in for you.

So, if you change the data type to

"dataType": {"name": "com.google.heart_minutes"}

It should work.

Then, you need to use the data source ID returned from that request for the data points.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • That's great and fixes the first error now I only get this error on the Data set request : message: "Unable to fetch DataSource for Dataset: raw:com.google.heart_minutes:292824132082:op:6:1000019" status: "INVALID_ARGUMENT" Thanks a lot for the answer! – Ben Cooper Jun 16 '20 at 16:37
  • @BenCooper please show the response that comes back when you create the data source. I don't believe the `29282...` part is correct. Where did you get that data source id from? – Andy Turner Jun 16 '20 at 18:09
  • I believe your hunch was right, I was using an old data source id it worked once I used the new one, as I was generating a new data source for every session, I guess this isn't necessary? and I should just continue to use the old one? Thanks a lot – Ben Cooper Jun 17 '20 at 16:09
  • No, you shouldn't be generating a new data source for every session. – Andy Turner Jun 17 '20 at 16:25
  • Thank you so much for the help, I have added an answer of my final working code :) – Ben Cooper Jun 17 '20 at 18:39
0

Awesome, so after some support in the comments I have some working code to add a new session with data from a previously defined data source using 3 API calls. The first call is to create a data source and only needs to be run once. The second and third then add a data point to a data set and creates a new session for the workout respectively. Here's the final working code:

Data Source:

/*
         gapi.client.fitness.users.dataSources.create({
             "userId":"me",
             "resource": {
                "application": {
                "name": "LittleWorkouts"
              },
              "dataType": {
                "name": "com.google.heart_minutes"
              },
              "device": {
                "manufacturer": "op",
                "model": "6",
                "type": "phone",
                "uid": "1000020",
                "version": "1"
              },
              "type": "raw"
             }
         })
        .then(function(response) {
                // Handle the results here (response.result has the parsed body).
                console.log("Response", response);
              },
              function(err) { console.error("Execute error 1", err); });
  */

Data and Data Set:

gapi.client.fitness.users.dataSources.datasets.patch({
      "dataSourceId":"raw:com.google.heart_minutes:108881196053:op:6:1000020",
      "userId": "me",
      "datasetId": z,
      "resource": {
  "minStartTimeNs": workoutStartTime * 1000000,
  "maxEndTimeNs": workoutEndTime * 1000000,
  "dataSourceId": "raw:com.google.heart_minutes:108881196053:op:6:1000020",
  "point": [
    {
        "originDataSourceId": "raw:com.google.heart_minutes:108881196053:op:6:1000020",
      "value": [
        {
          "fpVal": 8
        }
      ],
      "dataTypeName": "com.google.heart_minutes",
      "endTimeNanos": workoutEndTime * 1000000,
      "startTimeNanos": workoutStartTime * 1000000,
    }
  ]
}
    })
        .then(function(response) {
                // Handle the results here (response.result has the parsed body).
                console.log("Response", response);
              },
              function(err) { console.error("Execute error 2", err); });

Session:

gapi.client.fitness.users.sessions.update({
            "userId":"me",
            "sessionId": id,
            "id": id,
            "name": "Morning Workout",
            "description": "A very intense workout",
            "startTimeMillis": workoutStartTime,
            "endTimeMillis": workoutEndTime,
            "version": 1,
            "lastModifiedToken": "exampleToken",
            "application": {
                "detailsUrl": "http://example.com",
                "name": "LittleWorkouts",
                "version": "1.0"
            },
            "activityType": 21,
            "activeTimeMillis": workoutEndTime - workoutStartTime
            }).then((res) => {console.log(res)});
            console.log('res')
Ben Cooper
  • 35
  • 8