matinzd / react-native-health-connect

React native library for health connect (Android only)
http://matinzd.github.io/react-native-health-connect
MIT License
197 stars 41 forks source link

lateinit property requestPermission has not been initialized #117

Closed MohsinAliSoomro closed 1 month ago

MohsinAliSoomro commented 1 month ago

Describe the bug A clear and concise description of what the bug is.

To Reproduce Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Minimal Reproducible
Link to minimal reproducible code. It would be much easier for us to investigate the issue!

Environment:

matinzd commented 1 month ago

Hi,

Please fill out the template so that I can investigate. Please also follow the documentation carefully and make sure you have setup everything properly.

MohsinAliSoomro commented 1 month ago

@matinzd Here is my package.json { "name": "albahar-3", "version": "1.0.0", "main": "expo-router/entry", "scripts": { "start": "expo start", "android": "expo run:android", "ios": "expo run:ios", "web": "expo start --web", "build:android": "eas build -p android --profile preview" }, "dependencies": { "@react-native-async-storage/async-storage": "^1.21.0", "@react-native-community/datetimepicker": "7.7.0", "@react-native-community/netinfo": "^11.1.0", "@react-native-community/toolbar-android": "^0.2.1", "@react-native-masked-view/masked-view": "^0.3.0", "@react-native-picker/picker": "^2.6.1", "@react-native-segmented-control/segmented-control": "2.4.1", "@react-navigation/native": "^6.1.17", "ahooks": "^3.8.0", "amazon-cognito-identity-js": "^6.3.13", "aws-amplify": "^5.3.19", "aws-sdk": "^2.1651.0", "expo": "~50.0.19", "expo-constants": "~15.4.6", "expo-contacts": "~12.8.2", "expo-image": "~1.10.6", "expo-linear-gradient": "~12.7.2", "expo-linking": "~6.2.2", "expo-permissions": "^14.4.0", "expo-router": "~3.4.10", "expo-secure-store": "~12.8.1", "expo-sensors": "~12.9.1", "expo-status-bar": "~1.11.1", "install": "^0.13.0", "nativewind": "^2.0.11", "npm": "^10.8.1", "react": "18.2.0", "react-native": "^0.73.6", "react-native-health-connect": "^2.1.0", "react-native-pager-view": "^6.2.3", "react-native-phone-input": "^1.3.7", "react-native-reanimated-carousel": "^3.5.1", "react-native-safe-area-context": "4.8.2", "react-native-screens": "~3.29.0", "react-native-select-dropdown": "^4.0.1", "react-native-svg": "14.1.0", "usehooks-ts": "^3.1.0", "zustand": "^4.5.2" }, "devDependencies": { "@babel/core": "^7.20.0", "expo-build-properties": "^0.12.3", "expo-health-connect": "^0.1.0", "tailwindcss": "3.3.2" }, "private": true }

app.json { "expo": { "name": "Engage", "slug": "engage", "version": "1.0.0", "orientation": "portrait", "icon": "./assets/logo.png", "scheme": "albahar3", "userInterfaceStyle": "light", "splash": { "image": "./assets/logo.png", "resizeMode": "contain", "backgroundColor": "#ffffff" }, "assetBundlePatterns": ["*/"], "ios": { "infoPlist": { "LSApplicationQueriesSchemes": ["tel"], "NSContactsUsageDescription": "Allow ACT to access your contacts." }, "supportsTablet": true, "bundleIdentifier": "com.mohsinlisoomro.AlBahar3" }, "android": { "permissions": [ "android.permission.READ_CONTACTS", "android.permission.WRITE_CONTACTS", "android.permission.ACTIVITY_RECOGNITION", "android.permission.health.READ_STEPS", "android.permission.health.WRITE_STEPS", "android.permission.ACTIVITY_RECOGNITION", "PHONE_CALL" ], "adaptiveIcon": { "foregroundImage": "./assets/adaptive-icon.png", "backgroundColor": "#ffffff" }, "package": "com.user.AlBahar3" }, "web": { "favicon": "./assets/favicon.png", "bundler": "metro" }, "plugins": [ [ "expo-sensors", { "motionPermission": "Allow $(PRODUCT_NAME) to access your device motion" } ], "expo-router", [ "expo-contacts", { "contactsPermission": "Allow ACT to access your contacts." } ], "expo-secure-store", "expo-health-connect", [ "expo-build-properties", { "android": { "extraProguardRules": "-keep class com.amazonaws.* { ; }", "compileSdkVersion": 34, "targetSdkVersion": 34, "buildToolsVersion": "34.0.0", "minSdkVersion": 26 } } ] ], "extra": { "router": { "origin": false }, "eas": { "projectId": "projectid" } }, "owner": "act1" } }

const readData = async () => { console.log("CALLING..."); try { const isInitialized = await initialize(); console.log({ isInitialized }); getGrantedPermissions().then((permissions) => { console.log("Granted permissions ", { permissions }); }); //request permissions if (isInitialized) { // Here is getting error on permission const grantedPermissions = await requestPermission([ { accessType: "READ", recordType: "Steps" }, { accessType: "WRITE", recordType: "Steps" }, ]); console.log({ grantedPermissions }); } // } catch (error) { console.log({ error }); } }; useEffect(() => { readData(); });

matinzd commented 1 month ago

Are you using expo prebuild? Did you run expo prebuild -c?

MohsinAliSoomro commented 1 month ago

Yes. I am using expo Prebuild is working. It stuck on permissions

matinzd commented 1 month ago

Can you move expo-health-connect to dependencies instead of devDependencies?

MohsinAliSoomro commented 1 month ago

@matinzd brother, Actually it is android 14 when I write requestPermission function it crashed

matinzd commented 1 month ago

I can't understand what you mean. Did you try what I mentioned earlier?

JRP-Zeno commented 1 month ago

Hi, I'm also having this problem with permissions.

Error message: kotlin.UninitializedPropertyAccessException: lateinit property requestPermission has not been initialized dev.matinzd.healthconnect.permissions.HealthConnectPermissionDelegate.launch(HealthConnectPermissionDelegate.kt:32) dev.matinzd.healthconnect.HealthConnectManager$requestPermission$1$1.invokeSuspend(HealthConnectManager.kt:64) ...

I have beed able to build successfully using the following config:

app.json: "expo": { ... "plugins": [ ... ["expo-health-connect"], [ "expo-build-properties", { "android": { "compileSdkVersion": 34, "targetSdkVersion": 34, "minSdkVersion": 26 } } ],

package.json: "dependencies":{ "expo-health-connect": "^0.1.0", "react-native-health-connect": "^2.1.0", ... "devDependencies": { "expo-build-properties": "^0.12.3",

I have been testing the methods at https://matinzd.github.io/react-native-health-connect/docs/category/methods

initialize and getSdkStatus work as expected, but trying to call request permission as per the example here: requestPermission results in the app crashing with the error message above

Powablocks commented 1 month ago

Hello, I have the same problem when using it in a project using expo router. On another project without router it worked. I can share the two projects if you need.

JRP-Zeno commented 1 month ago

Hi, Yeah if you don't mind sharing that would be great to see them. I am use expo router so that might match up with my problem.

Powablocks commented 1 month ago

Working project (Without expo) : https://drive.proton.me/urls/8F31TXYXQ0#0VdhI4ACnEmR Not working (with expo) : https://drive.proton.me/urls/MJPCZZ5KMG#iO0SCay1o8RU I've removed firebase file in second project you might need to remove the callings if you want to compile it

MohsinAliSoomro commented 1 month ago

Can you move expo-health-connect to dependencies instead of devDependencies?

yes but it is not working

MohsinAliSoomro commented 1 month ago

I can't understand what you mean. Did you try what I mentioned earlier?

It means, my an android version is 14 my phone. and earlier solution is not working at all

martinbean commented 1 month ago

I’m getting this error, too. Literally just created a new React Native Expo app based on the “Get started” tutorial on the React Native website. This happens on both a real device, and in a virtual device running Android 14 (API 34).

I’m new to React Native, so do let me know what information I can provide to help diagnose.

matinzd commented 1 month ago

Can everyone try this example here and see if it works?

https://github.com/matinzd/expo-health-connect/tree/main/example

This example is using Expo Prebuild. I have tested it on most Android versions and it's working.

matinzd commented 1 month ago

Hello, I have the same problem when using it in a project using expo router. On another project without router it worked. I can share the two projects if you need.

I can't relate why this would not work on expo router app. Are you using Expo Prebuild or Expo Go?

MohsinAliSoomro commented 1 month ago

Can everyone try this example here and see if it works?

https://github.com/matinzd/expo-health-connect/tree/main/example

This example is using Expo Prebuild. I have tested it on most Android versions and it's working.

please also confirm it is built on expo.dev as well right?

matinzd commented 1 month ago

What do you mean? Yes the example project is basically an Expo project that has prebuild functionality.

Note: You cannot use this library with Expo Go.

Clone the repo. Install the dependencies and run the example. Are you all new to Expo/RN?

Are you confused with the differences with Expo Go / Prebuild / Bare?

JRP-Zeno commented 1 month ago

Can everyone try this example here and see if it works?

https://github.com/matinzd/expo-health-connect/tree/main/example

This example is using Expo Prebuild. I have tested it on most Android versions and it's working.

I just tried a build with this example app and encountered the same problem.

matinzd commented 1 month ago

Can everyone try this example here and see if it works?

https://github.com/matinzd/expo-health-connect/tree/main/example

This example is using Expo Prebuild. I have tested it on most Android versions and it's working.

I just tried a build with this example app and encountered the same problem.

What Android version? Did you run expo prebuild?

What do you mean by build with this? Did you actually try the example or you tried to adjust your application code based on the example?

matinzd commented 1 month ago

Here is the example working with Expo Prebuild:

Screenshot 2024-07-25 at 08 43 21
VinceReid commented 1 month ago

Hi, I have the same issue. The example you provided works fine.

Does the example use the config-plugin in the src/withHealthConnect.ts instead of the module folder?

I also noticed some extra configuration in the example webpack.config.js (dangerouslyAddModulePathsToTranspile), metro.config.js (blockList and extraNodeModules) and tsconfig.json (paths) in example/* is this required for the module to work properly?

Thanks

matinzd commented 1 month ago

No.

JavaScript configurations should not affect native modules usually.

Webpack configuration is mostly for the web and that should not affect the android module.

Try cleaning your prebuild and see if it works, although not cleaning it should not cause an issue.

lsandini commented 1 month ago

I have the same problem. Basic Expo project SDK 51, apk built with "eas build --profile development --platform android --output dist/dev-stepper.apk --local". Also tried prebuilding locally first, same result.

The dev build installs fine, but pressing REQUEST SAMPLE PERMISSIONS results in the error below :

image

Reading sample data or aggregated data works :

image

lsandini commented 1 month ago

I found a simple solution, I hope it works for you too.

In my app.json, I had the plugins in the following order :

"plugins": [
  "expo-router",
  "expo-health-connect",
  [
    "expo-build-properties",
    {
      "android": {
        "compileSdkVersion": 34,
        "targetSdkVersion": 34,
        "minSdkVersion": 26
      }
    }
  ],
  "react-native-health-connect"
]

I re-ordered them placing react-native-health-connect BEFORE expo-build-properties, and bam, problem gone.

"plugins": [
  "expo-router",
  "expo-health-connect",
  "react-native-health-connect",
  [
    "expo-build-properties",
    {
      "android": {
        "compileSdkVersion": 34,
        "targetSdkVersion": 34,
        "minSdkVersion": 26
      }
    }
  ]
]

Also, I saved the state of the initialization and added some error handling to grantedPermissions() :

export default function App() {
  const [isInitialized, setIsInitialized] = useState(false);

  useEffect(() => {
    initializeHealthConnect();
  }, []);

  const initializeHealthConnect = async () => {
    try {
      await initialize();
      setIsInitialized(true);
      console.log('Health Connect initialized successfully');
    } catch (error) {
      console.error('Failed to initialize Health Connect:', error);
    }
  };

  const grantedPermissions = async () => {
    try {
      if (!isInitialized) {
        console.warn('Health Connect is not initialized yet');
        return;
      }
      const permissions = await getGrantedPermissions();
      console.log("Granted permissions ", { permissions });
    } catch (error) {
      console.error("Error getting granted permissions:", error);
      if (error instanceof Error) {
        console.error("Error name:", error.name);
        console.error("Error message:", error.message);
        console.error("Error stack:", error.stack);
      }
    }
  };
}
VinceReid commented 1 month ago

Hi @lsandini, Have you tried calling requestPermission()? This is where there error is occurring for me.

I was using expo-stack (expo-router, firebase, tamagui, tabs + drawer set-up) and could not figure out why it would not work. However I started a new project using a more basic set up 'tamagui@latest --template expo-router' and it works. I will manually add in the rest of the modules and hopefully not hit the same issue.

lsandini commented 1 month ago

You're right @VinceReid,

While getGrantedPermissions() now works for me, requestPermissions() and of course any function calling requestPermissions() still trigger the error :(

I just made a new expo project with blank template (no router), same error.

https://github.com/lsandini/stepper (SDK51, expo-router, typescript) https://github.com/lsandini/stepper-n (SDK51, no router, JS)

matinzd commented 1 month ago

@lsandini Please move expo-health-connect to dependencies in both projects.

{
  "name": "stepper-n",
  "version": "1.0.0",
  "main": "expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web"
  },
  "dependencies": {
    "expo": "~51.0.22",
    "expo-status-bar": "~1.12.1",
    "react": "18.2.0",
    "react-native": "0.74.3",
    "react-native-health-connect": "^2.1.0",
+   "expo-health-connect": "^0.1.0"
    "expo-dev-client": "~4.0.20"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "expo-build-properties": "^0.12.3",
-   "expo-health-connect": "^0.1.0"
  },
  "private": true
}

Also you are using Expo Go instead of Expo Prebuild. Your scripts are expo start --android and expo start --ios. You need to use development build. Hope that helps.

Also you don't need to add react-native-health-connect to app.json anymore. expo-health-connect should be enough.

lsandini commented 1 month ago

Thanks for your input.

I did the modifications mentionned above, and I am running a development build, not Expo Go.

Prebuild creates the android folder without problems. I can run "./gradlew :app:assembleDebug" in there or create my development build with eas, the result is identical unfortunately. Stuck here I am afraid :/

VinceReid commented 1 month ago

I think the issue is potentially a conflict with 'expo-dev-client'

I removed 'expo-dev-client' and related 'expo-dev-launcher' from my 'package.json' and removed 'expo-dev-launcher' plugin from 'app.json'. Cleaned pre-build, removed and re-installed all modules, then 'expo run:android' and it worked.

lsandini commented 1 month ago

Excellent Vince, that works for me too. 😃 How did you come to this conclusion, trial and error, or did you find a hint somewhere ?

But now I am wondering how I'll be making a dev build APK file without expo-dev-client... maybe by installing expo-dev-client as dev dependency ?

VinceReid commented 1 month ago

Glad to hear that it works for you too @lsandini

It was trial and error.

Might be worth trying it in dev dependencies just to check.

I'm not 100% sure if I'm correct in saying this as I'm fairly new to expo - you should be able to generate APK files without expo-dev-client by using the EAS CLI, but you'll have reduced debugging capabilities for local builds.

RM-Smilamind commented 1 month ago

Removing expo-dev-client dependency fixed the issue for me too

matinzd commented 1 month ago

I still can't relate how expo-dev-client can affect this module. Keep in mind that EDC will be stripped from the release build.

@kudo @brentvatne Any ideas?

lsandini commented 1 month ago

I understand EDC is stripped from preview/production builds, and probably the problem doesn't exist outside dev builds (?).

In my preview build, the "REQUEST SAMPLE PERMISSIONS" correctly triggers the requestPermissions() and opens the Health Connect permissions dialog.

But I wonder @matinzd, have you tried compiling a dev build as an .apk file, and are you seeing the same error when running a development server and a dev build on a physical device ?

I am quite depending on a physical device for other functionalities of my app. Although this is not a huge issue, it would be interesting to get to the bottom of it.

matinzd commented 1 month ago

Please try expo-health-connect v0.1.1 and let me know if the issue is fixed with the presence of expo-dev-client.

lsandini commented 1 month ago

@matinzd : yes, the issue is fixed for me ! That was way out of my league, thanks for your very prompt support ! :)

matinzd commented 1 month ago

Nice! I am gonna close this issue ✌️

VinceReid commented 1 month ago

Thanks so much @matinzd 👍