I have a react native app with an android native java module that accesses my local Google Fit healthstore using the Java Google Fit SDK:

        DataReadRequest readRequest = new DataReadRequest.Builder()
            .enableServerQueries()
            .aggregate(DataType.AGGREGATE_STEP_COUNT_DELTA)
            .bucketByTime(interval, TimeUnit.SECONDS)
            .setTimeRange(start, end, TimeUnit.MILLISECONDS)
            .build();

        Fitness.getHistoryClient(getReactContext(), getGoogleAccount())
            .readData(readRequest)
            .addOnSuccessListener(response -> {
                for (Bucket bucket : response.getBuckets()) {
                    for (DataSet dataSet : bucket.getDataSets()) {
                        readDataSet(dataSet);
                    }
                }

                try {
                    getCallback().onComplete(getReport().toMap());
                } catch (JSONException e) {
                    getCallback().onFailure(e);
                }
            })
            .addOnFailureListener(e -> getCallback().onFailure(e));

My problem is that for some start and end intervals for a particular user, the code gets stuck in the HistoryClient's .readData(readRequest), never resolving to the onSuccessListener or onFailureListener callbacks. In one particular case, to correct this, I can vary the start or end date to reduce the range, and suddenly the history client returns a data response. There doesn't seem to be any pattern of this bug relative to the start and end of the readRequest. In this case, the range was only over a week or so. Note that there are only about 100 steps in the requested range.

I initially thought that some data samples in Google Fit may be corrupt, thus reducing the range of the request would miss these samples, hence explaining why it may suddenly work by tinkering with start and end. However, by repositioning the start and end to explicitly cover these suspected samples, Google Fit works normally and a response is returned. I can timeout the async call using a CompletableFuture, therefore I know there is a .readData thread spinning in there somewhere? No exception is thrown.

I have set up all relevant read permissions in my google account's oAuth credentials - I can verify in my user account settings that the connected app indeed has these health data read permissions. The scope I request in the native code is

DataType.AGGREGATE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ

and I am using

'com.google.android.gms:play-services-fitness:21.1.0'
'com.google.android.gms:play-services-auth:21.0.0'

in my android build file. I have noticed the problem for both react-native 0.65.3 (android targetSdkVersion 31, compileSdkVersion 31) and react-native 0.73.2 (android targetSdkVersion 34, compileSdkVersion 34).

Are there any further steps I can take to diagnose the bug? When viewing the date range in Google Fit app, I see no problem and the step counts are there.

EDIT

I used logcat to scan for Google Fit log entries.

03-13 00:31:15.826  2696 24944 W Fitness : Error delivering batch 2. Attempt #1 [CONTEXT service_id=17 ]
03-13 00:31:15.826  2696 24944 W Fitness : android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died, but this could also be caused by running out of binder buffer space

Similar error seen in this android question

0

There are 0 best solutions below