Search code examples
androidgoogle-fitgoogle-fit-sdkgoogle-fit-apigoogle-fitness-api

Google Fit does not show the data sent by our app through the Android SDK


When try send data to Google Fit trougth SDK Android (not API), The data not appear inmediatly in Google Fit, they are steps that I do:

  1. I getting data from our API (this sessions are gets from our devices and our build data's structure from ours machines using IoT); then getting this data in .json format, by example:

{ "data": [ { "id": "aa8329a1-9841-4f94-8911-06500e11d17b", "startTime": "2022-06-11 12:11:18", "finishTime": "2022-06-11 12:43:18", "type": 2, "distance": 0.069394 } ] }

and then, send this info by trougth steps (only we want store field's distance for now)

  1. Make Google signin:
GoogleSignInOptions
            .Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .requestServerAuthCode(BuildConfig.WEB_CLIENT_GOOGLE_FIT)
            .requestIdToken(BuildConfig.WEB_CLIENT_GOOGLE_FIT)
            .requestScopes(
                Scope("https://www.googleapis.com/auth/fitness.activity.write"),
                Scope("https://www.googleapis.com/auth/fitness.heart_rate.write"),
                Scope("https://www.googleapis.com/auth/fitness.location.write"),
                Scope("https://www.googleapis.com/auth/fitness.activity.read"),
                Scope("https://www.googleapis.com/auth/fitness.location.read"))
            .build()
  1. Then, define fitness options with your Datatypes:
FitnessOptions
            .builder()
            .addDataType(DataType.AGGREGATE_DISTANCE_DELTA, FitnessOptions.ACCESS_WRITE)
            .addDataType(DataType.AGGREGATE_CALORIES_EXPENDED, FitnessOptions.ACCESS_WRITE)
            .addDataType(DataType.AGGREGATE_SPEED_SUMMARY, FitnessOptions.ACCESS_WRITE)
            .addDataType(DataType.TYPE_HEART_RATE_BPM, FitnessOptions.ACCESS_WRITE)
            .addDataType(DataType.AGGREGATE_HEART_POINTS, FitnessOptions.ACCESS_WRITE)
            .addDataType(DataType.TYPE_POWER_SAMPLE, FitnessOptions.ACCESS_WRITE)
            .build()
  1. I wish record only for now, save to Google Fit distance's parameter: //DISTANCE
val distanceDataSource = DataSource.Builder()
                .setAppPackageName("com.bodytone.zapp.dev")
                .setDataType(DataType.AGGREGATE_DISTANCE_DELTA)
                .setStreamName("session-data-distance")
                .setType(DataSource.TYPE_RAW)
                .build()
  1. Create datapoint:
val distance = DataPoint.builder(distanceDataSource)
                .setTimeInterval(training1.getStartDateInMillis(), training1.getFinishDateInMillis(), TimeUnit.MILLISECONDS)
                .setField(Field.FIELD_DISTANCE, training1.distance.toFloat())
                .build()
  1. Builder data set with these configurations:
val distanceDataSet = DataSet.builder(distanceDataSource)
                .add(distance)
                .build()
  1. Make a insert request:
val insertRequest = SessionInsertRequest.Builder()
                .setSession(session)
                .addDataSet(distanceDataSet)
                .build()
  1. Create a session client with insertRequest:
Fitness.getSessionsClient(requireActivity(), GoogleSignIn.getAccountForExtension(requireActivity(), fitnessOptions))
                .insertSession(insertRequest)
                .addOnSuccessListener {
                    Toast.makeText(requireActivity(), "Session insert was successful!", Toast.LENGTH_LONG).show()
                }
                .addOnCanceledListener {
                    Toast.makeText(requireActivity(), "Session insert was cancelled!", Toast.LENGTH_LONG).show()
                }
                .addOnFailureListener {
                    it.printStackTrace()
                    Toast.makeText(requireActivity(), "There was a problem inserting the session: ${it.message}", Toast.LENGTH_LONG).show()
                }
                .continueWith{
                    verifySession(training1)
                }

for now, always getting a message from addOnSuccessListener, so we believe that these data's are store in Google Fit, because getting a message from addOnSuccessListener() that say "Session insert was successful!"

once finish insertRequest, we use in continueWith a method verifySession(training1) to verify that this was inserted successful:

Fitness.getSessionsClient(requireActivity(), GoogleSignIn.getAccountForExtension(requireActivity(), fitnessOptions))
            .readSession(request)
            .addOnSuccessListener { sessionReadResponse ->
                // Get a list of the sessions that match the criteria to check the result.
                val sessions = sessionReadResponse.sessions
                Log.i("Bodytone", "Session read was successful. Number of returned sessions is: ${sessions.size}")
                for (session in sessions) {
                    // Process the session
                    dumpSession(session)
                    // Process the data sets for this session
                    val dataSets = sessionReadResponse.getDataSet(session)
                    for (dataSet in dataSets) {
                        dumpDataSet(dataSet)
                    }
                }
            }
            .addOnFailureListener {
                Timber.i("Error reading: ${it.message}")
            }

Then, getting the data store in Google Fit trougth method readSession, and we can observe that these data are show successfull!!! We can see this session store from this method!!

Now, the issue that we are, Why if store data successful in Google Fit, this not show in Google Fit App? besides that we have wait 30 minutes aprox to see if this data was store en Google Fit, altougth as we showed above, the session was store successful, then recovery this session and show, all is fine! Why not appear this session in Google Fit, if all is fine (Google Fit not show errors) all is fine...¿That could be happening with Google Fit?

PD: The configuration google console is fine, all working id package, identifier sha1, consent window oauth is fine (test mode) with a test user for now; the profile that we use to see Google's session is with this user test too; simply not appear the data send to Google Fit in App Google Fit (this has our app approved in your connected apps and yours Google Access signin)

Some help, sample in git (working) ?

Thanks a lot!!


Solution

  • I had another problem with Google Fit, which is quite similar to yours. I write to Google Fit support and ask for some help, and here is the answer they provided:

    "... you are currently using the native Android library for Google Fit. This has been deprecated since May 2022 and we no longer encourage developers to use it. The REST APIs however are still active and what we recommend for developers to use moving forward. Another option is to use Android Health Connect...".

    So this is what I tell to you: migrate to REST API or use Health Connect.