cph-cachet / flutter-plugins

A collection of Flutter plugins developed by CACHET
546 stars 657 forks source link

[Health 4.4.0] hasPermission and requestAuthorization doesnt work if app revoked in Google Fit settings #640

Open rafaellop opened 1 year ago

rafaellop commented 1 year ago

Device / Emulator and OS

Describe the bug

I can successfully requestAuthorization for the first time and access can check hasPermissions as well as download Google Fit data. However when I removed my app from the list of connected apps in the Google Fit app / Profile / Settings / Manage connected apps the hasPermission still returns true while the app has no permission.

To Reproduce

Call requestAuthorization and allow app to access Google Fit. Then remove the app using Google Fit app interface (/ Profile / Settings / Manage connected apps) and try again to request auth or check permissions using hasPermissions()

Expected behavior

After app is removed from the connected apps in the Google Fit app, the hasPermissions function should return false and the requestAuthorization function should allow authorization again.

Actual behavior

hasPermissions always returns true if connected app is removed using Google Fit app. requestAuthorization has no effect in this case.

Flutter doctor

[√] Flutter (Channel stable, 3.3.10, on Microsoft Windows [Version 10.0.22000.1335])
[√] Android toolchain - develop for Android devices (Android SDK version 32.0.0)
[√] Chrome - develop for the web
[√] VS Code (version 1.74.2)
[√] Connected device (4 available)
[√] HTTP Host Availability
rafaellop commented 1 year ago

Update, it seems that the change in the Google Fit app (Google account indeed) isn't available immediately on the device. However the hasPermissions() still returns true so I call the getHealthDataFromTypes() and get an exception:

I/FLUTTER_HEALTH::ERROR( 9449): 4: The user must be signed in to make this API call.
I/FLUTTER_HEALTH::ERROR( 9449): [Ljava.lang.StackTraceElement;@c02cb5c

If I try to call requestAuthorization() it returns true as it was granted but it's not. Any try to get data from the API throws exception as above and nothing can be done.

rafaellop commented 1 year ago

It seems there's a bug in the Google Fit or the same behavior as on iOS (where hasPermissions() has no use). People reported this for example here https://github.com/android/fit-samples/issues/28

Because of this the only solution at the moment is to not use the hasPermissions() at all. Unfortunately the Android implementation of the requestAuthorization() checks permissions the same way like for the hasPermissions() and doesn't allow to authorize the app again for Google Fit use because hasPermissions() returns true even if there are no rights at all.

I've decided to post a PR to the Android implementation and just not check the permissions in the requestAuthorization(). From what I tested if permissions are assigned the autorization dialog is not shown at all so the permission check is in the GoogleSignIn.requestPermissions() itself and we don't need to check this again before calling it.

https://github.com/cph-cachet/flutter-plugins/commit/cc54c8e614d69f0e51be4664b680fcb90231dfb4

MadsVSChristensen commented 1 year ago

I've added the option to revokePermissions in version 4.6.0, however it uses disableFit instead of revokeAccess. It seems the revokeAccess creates a bug when trying to request permissions afterwards, but disableFit removes authorization for the user in a different manner.

I'll let the issue stand in case other developers have used revokeAccess and struggles with this.

edocabhi commented 1 year ago

@MadsVSChristensen Could you please elaborate on how disableFit works. Also, how can we check if disableFit was called and if the app can / cannot access health data. Is there a method similar to hasPermissions() that can be leveraged?