StasDoskalenko/react-native-google-fit

Error: 5000: Application needs OAuth consent from the user

Waltari10 opened this issue · 2 comments

I had Google Fit working previously, but all of a sudden I'm getting this error. I didn't use it for a week or two, but now when I try to get exercises it returns this error instead:

Error: 5000: Application needs OAuth consent from the user

All GoogleFit.isEnabled, GoogleFit.isAuthorized and GoogleFit.isAvailable are returning true, just before this error is thrown. However it seems it's not authorized somehow?

I do get the pop up dialog to select which google account I want to use. However it does not show the dialog which asks for access to Exercise data. It did show it before, but not anymore somehow.

In GCP I have a project with an Android OAuth Client, which has the scope to read exercise data.

Any idea what I could be doing wrong?

How I'm using the library currently:

async function isGoogleFitAuthorized(): Promise<boolean> {
  try {
    await GoogleFit.checkIsAuthorized();
    return GoogleFit.isAuthorized;
  } catch (error) {
    Monitoring.error(
      error,
      "[Google Fit] Error trying to authorize Google Fit"
    );
  }

  return false;
}

const isGoogleFitEnabled = (): Promise<boolean> =>
  new Promise(res => {
    GoogleFit.isEnabled((err, isEnabled) => {
      if (err) {
        res(false);
      } else if (isEnabled) {
        res(true);
      } else {
        res(false);
      }
    });
  });

const isGoogleFitAvailable = (): Promise<boolean> =>
  new Promise(res => {
    GoogleFit.isAvailable((err, isAvailable) => {
      if (err) {
        res(false);
      } else if (isAvailable) {
        res(true);
      } else {
        res(false);
      }
    });
  });

type GoogleFitWorkoutSessionOptions = Parameters<
  typeof GoogleFit.getWorkoutSession
>[0];

type ExerciseAndroid = {
  id: string;
  from: number;
  to: number;
  activityId: number;
  activityName: string;
  sourceName: string;
  sourceId: string;
  calories: number;
  distance?: number;
};

export const fetchExerciseDataAndroid =
  (defaultFetchScope: number) =>
  async (
    from: number = Date.now() - defaultFetchScope,
    to: number = Date.now(),
    limit: number = 30
  ): Promise<ExerciseAndroid[]> => {
    await initGoogleFit();

    await GoogleFit.checkIsAuthorized();

    const authOptions = {
      scopes: [Scopes.FITNESS_ACTIVITY_READ],
    };

    const authResponse = await GoogleFit.authorize(authOptions);

    console.log(authResponse); // {"success": true}

    if (
      !(await isGoogleFitEnabled()) ||
      !(await isGoogleFitAvailable()) ||
      !(await isGoogleFitAuthorized()) ||
      from >= to
    ) {
      return [];
    }

    const options: GoogleFitWorkoutSessionOptions = {
      startDate: new Date(from).toISOString(),
      endDate: new Date(to).toISOString(),
      readSessionFromAllApps: true,
    };

    const workouts = await GoogleFit.getWorkoutSession(options);
    console.log("workouts", workouts); // Error: 5000: Application needs OAuth consent from the user
  };

Seemed this was due to location permission. I added:

   const options = {
        scopes: [Scopes.FITNESS_ACTIVITY_READ, Scopes.FITNESS_LOCATION_READ],
      };

And to AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

And the error went away.

It was confusing because it worked at first without those. Not sure at all what happened there.

Pretty confusing error message for not having the correct scopes or permissions in manifest