expo: [SDK 49] react-native-maps crashes app with location permission

Minimal reproducible example

https://github.com/ChromeQ/expo-sdk49-maps

Summary

I have an existing app working well with maps on expo-sdk48. After upgrade to sdk49 the app crashes on load.

I have found that the app only crashes when location permission is turned on, and when react-native-maps uses the showUserLocation prop, and when in development build (and probably production build). Interestingly Expo Go does work. I have not tested iOS.

I have created a minimal reproduction repo - https://github.com/ChromeQ/expo-sdk49-maps The main branch is the initial commit from a simple create-expo-app I created several branches with PR’s to easily review the difference and progressively upgraded react-native-maps to latest, then expo sdk to 49 where it crashes on load.

I believe this is a bug within expo rather than react-native-maps, as this new sdk is new (react-native-maps@1.7.1 has been stable since 23rd April. And expo sdk 48 also works with the latest maps version. The only change between my branches is expo upgrade (and the required dependencies it requires)

Environment

❯ npx expo-env-info

expo-env-info 1.0.5 environment info: System: OS: Linux 5.19 Ubuntu 22.04.2 LTS 22.04.2 LTS (Jammy Jellyfish) Shell: 5.1.16 - /bin/bash Binaries: Node: 18.16.1 - ~/.nvm/versions/node/v18.16.1/bin/node Yarn: 1.22.19 - ~/.yarn/bin/yarn npm: 9.5.1 - ~/.nvm/versions/node/v18.16.1/bin/npm SDKs: Android SDK: Android NDK: 25.2.9519653 npmPackages: expo: ^49.0.0 => 49.0.0 react: 18.2.0 => 18.2.0 react-native: 0.72.1 => 0.72.1 Expo Workflow: managed

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 35 (9 by maintainers)

Commits related to this issue

Most upvoted comments

Im having this exact same issue, but only in bundle release app that is downloaded from Play Store. Running the app with the bundler or with debug APK doesn´t do this. react-native-maps 1.7.1 expo-location 16.1.0 sdk 49

A new version of expo-location fixing this issue has just been published to npm

Please upgrade to v16.1.0 by running yarn add expo-location@16.1.0 or npx expo install --fix

Happy Coding! 🎉

@ChromeQ - i appreciate all of your research into this! thank you.

the whole point of Expo is to guarantee (as much as possible) that a known version of set of dependencies work as expected with the SDK. And the SDK 49 upgrades react-native-maps to 1.7.1 which has this known limitation.

this is indeed one of the benefits that we aim to offer. as you can imagine, with the surface area of the expo sdk, it’s not always possible to cover every case. in https://github.com/expo/expo/pull/22908, @aleqsio followed our qa process to test react-native-maps within this repo, but this doesn’t always work exactly the same as other projects and we don’t exercise the entirety of the API for every third party module. for third party modules, it’s more of an smoke test, and we trust that those modules follow their own processes for qa before releasing. our smoke test did not include the showsUserLocation prop. we had a beta period for a week and this was also not encountered at that time. immediately after a release, we often uncover new issues that were not surfaced in qa or beta.

in the future, if you wait a couple weeks after a release, these types of issues will likely be handled already, or warnings will be in place to let folks know about them. we missed this particular regression and i’m sure we’ll miss some in the future as well. our response in these types of situations is to try to handle the issue quickly, while also empowering developers to work around the issue on their own, rather than being blocked on us. i’m happy that you’ve identified a workaround and have this resolved on your end. @gabrieldonadel is currently looking into the best way for us to solve this on our end, and i’ve added a note to the “Known Regressions” in the release notes.

thanks again for the report and all of the followup here.

@niug I had faced similar Issue. Updating my android/build.gradle with below changes solved it for me. you can try this solution.

allprojects {
    subprojects {
        project.configurations.all {
            resolutionStrategy.eachDependency { details ->
                if (details.requested.group == 'com.google.android.gms'
                        && details.requested.name == 'play-services-location') {
                    details.useVersion '20.0.0'
                }
            }
        }
    }
}

@niug The fix I outlined above with upgrading react-native-maps to beta version will only work with expo-location@16.0.0 – expo location updated to avoid using the beta of maps.

You can downgrade react-native-maps to 1.7.1 and keep expo-location on 16.1.0 or You can keep react-native-maps on the beta and downgrade expo-location to 16.0.0

I downgraded the dependency to the one that was used in sdk 48. IIRC that was 1.3.2 and all reported issues from the Google play store prerelease report are gone. So I think I will go with that for now.

I fixed this error by changing the version of react-native-maps to 2.0.0-beta.14.

The issue has been fixed in version v.2.0.0-beta.10

I can confirm my app is working as expected with the beta version of react-native-maps with no regressions so far. Also new with expo sdk 49 is the ability to ignore dependency checking for expo-doctor or expo install --check, just add this to your package.json

"expo": {
    "install": {
      "exclude": [
        "react-native-maps"
      ]
    }
  }

More info: https://docs.expo.dev/more/expo-cli/#configuring-dependency-validation

The error only happens in standalone build (not Expo Go) so I added a yarn build script to package.json. This should ask to setup a project in expo. You will also need a google maps api key in app.json.

The app will ask for location permission on load, and if granted will crash the app. It also only happens when react-native-maps uses showUserLocation so you can run the app by changing the variable in the App.js.

The app crashes with java.lang.RuntimeException: Unable to resume activity and Caused by java.lang.IncompatibleClassChangeError: Found interface com.google.android.gms.location.FusedLocationProviderClient, but class was expected seems to be the main culprit.

The full error stack trace
ERROR  Your app just crashed. See the error below.
java.lang.RuntimeException: Unable to resume activity {com.chromeq.exposdk49maps/com.chromeq.exposdk49maps.MainActivity}: java.lang.reflect.InvocationTargetException
 android.app.ActivityThread.performResumeActivity(ActivityThread.java:4773)
 android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4806)
 android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:57)
 android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
 android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:179)
 android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
 android.app.ActivityThread$H.handleMessage(ActivityThread.java:2306)
 android.os.Handler.dispatchMessage(Handler.java:106)
 android.os.Looper.loopOnce(Looper.java:201)
 android.os.Looper.loop(Looper.java:288)
 android.app.ActivityThread.main(ActivityThread.java:7918)
 java.lang.reflect.Method.invoke(Native Method)
 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
Caused by java.lang.reflect.InvocationTargetException
 java.lang.reflect.Method.invoke(Native Method)
 expo.modules.ReactActivityDelegateWrapper.invokeDelegateMethod(ReactActivityDelegateWrapper.kt:274)
 expo.modules.ReactActivityDelegateWrapper.onResume(ReactActivityDelegateWrapper.kt:152)
 com.facebook.react.ReactActivity.onResume(ReactActivity.java:58)
 android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1564)
 android.app.Activity.performResume(Activity.java:8474)
 android.app.ActivityThread.performResumeActivity(ActivityThread.java:4763)
 android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4806)
 android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:57)
 android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
 android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:179)
 android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
 android.app.ActivityThread$H.handleMessage(ActivityThread.java:2306)
 android.os.Handler.dispatchMessage(Handler.java:106)
 android.os.Looper.loopOnce(Looper.java:201)
 android.os.Looper.loop(Looper.java:288)
 android.app.ActivityThread.main(ActivityThread.java:7918)
 java.lang.reflect.Method.invoke(Native Method)
 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
Caused by java.lang.IncompatibleClassChangeError: Found interface com.google.android.gms.location.FusedLocationProviderClient, but class was expected (declaration of 'com.google.android.gms.location.FusedLocationProviderClient' appears in /data/app/~~VOCIH5e3WgYMx6lMYYEu5g==/com.chromeq.exposdk49maps-WO1q4VNP9CUd5w5AJxosVw==/base.apk)
 com.rnmaps.maps.FusedLocationSource.activate(FusedLocationSource.java:49)
 com.google.android.gms.maps.zzs.activate(com.google.android.gms:play-services-maps@@18.0.0:1)
 com.google.android.gms.maps.internal.zzj.zza(com.google.android.gms:play-services-maps@@18.0.0:6)
 com.google.android.gms.internal.maps.zzb.onTransact(com.google.android.gms:play-services-maps@@18.0.0:3)
 android.os.Binder.transact(Binder.java:1164)
 m.fe.c(:com.google.android.gms.dynamite_mapsdynamite@232414044@23.24.14 (190400-0):2)
 com.google.android.gms.maps.internal.l.e(:com.google.android.gms.dynamite_mapsdynamite@232414044@23.24.14 (190400-0):0)
 com.google.maps.api.android.lib6.impl.bk.F(:com.google.android.gms.dynamite_mapsdynamite@232414044@23.24.14 (190400-0):6)
 com.google.android.gms.maps.internal.i.bb(:com.google.android.gms.dynamite_mapsdynamite@232414044@23.24.14 (190400-0):204)
 m.ff.onTransact(:com.google.android.gms.dynamite_mapsdynamite@232414044@23.24.14 (190400-0):4)
 android.os.Binder.transact(Binder.java:1164)
 com.google.android.gms.internal.maps.zza.zzc(com.google.android.gms:play-services-maps@@18.0.0:2)
 com.google.android.gms.maps.internal.zzg.setLocationSource(com.google.android.gms:play-services-maps@@18.0.0:3)
 com.google.android.gms.maps.GoogleMap.setLocationSource(com.google.android.gms:play-services-maps@@18.0.0:2)
 com.rnmaps.maps.MapView$15.onHostResume(MapView.java:424)
 com.facebook.react.bridge.ReactContext.onHostResume(ReactContext.java:308)
 com.facebook.react.ReactInstanceManager.moveToResumedLifecycleState(ReactInstanceManager.java:778)
 com.facebook.react.ReactInstanceManager.onHostResume(ReactInstanceManager.java:677)
 com.facebook.react.ReactInstanceManager.onHostResume(ReactInstanceManager.java:627)
 com.facebook.react.ReactDelegate.onHostResume(ReactDelegate.java:70)
 com.facebook.react.ReactActivityDelegate.onResume(ReactActivityDelegate.java:123)
 java.lang.reflect.Method.invoke(Native Method)
 expo.modules.ReactActivityDelegateWrapper.invokeDelegateMethod(ReactActivityDelegateWrapper.kt:274)
 expo.modules.ReactActivityDelegateWrapper.onResume(ReactActivityDelegateWrapper.kt:152)
 com.facebook.react.ReactActivity.onResume(ReactActivity.java:58)
 android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1564)
 android.app.Activity.performResume(Activity.java:8474)
 android.app.ActivityThread.performResumeActivity(ActivityThread.java:4763)
 android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4806)
 android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:57)
 android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
 android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:179)
 android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
 android.app.ActivityThread$H.handleMessage(ActivityThread.java:2306)
 android.os.Handler.dispatchMessage(Handler.java:106)
 android.os.Looper.loopOnce(Looper.java:201)
 android.os.Looper.loop(Looper.java:288)
 android.app.ActivityThread.main(ActivityThread.java:7918)
 java.lang.reflect.Method.invoke(Native Method)
 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)