[Bug]: Usage of `UserLocation` causes app crash on Android when new arch is disabled
Mapbox Implementation
Mapbox
Mapbox Version
default
React Native Version
0.76.7
Platform
Android
@rnmapbox/maps version
10.1.37
Standalone component to reproduce
import React, { useEffect, useState } from "react";
import { StyleSheet, View } from "react-native";
import Mapbox from "@rnmapbox/maps";
const App = () => {
const [ready, setReady] = useState(false);
useEffect(() => {
Mapbox.requestAndroidLocationPermissions()
.then((isGranted) => {
setReady(isGranted);
})
.catch(console.error);
}, [setReady]);
return (
<View style={styles.page}>
<View style={styles.container}>
{ready ? (
<Mapbox.MapView style={styles.map}>
{/* 👇 Issue goes away when removing this line. */}
<Mapbox.UserLocation />
</Mapbox.MapView>
) : null}
</View>
</View>
);
};
export default App;
const styles = StyleSheet.create({
page: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
container: {
height: 300,
width: 300,
},
map: {
flex: 1,
},
});
Observed behavior and steps to reproduce
The app completely crashes, with the following error message (seen via adb logs):
03-03 16:29:09.956 17182 17182 E AndroidRuntime: FATAL EXCEPTION: main
03-03 16:29:09.956 17182 17182 E AndroidRuntime: Process: com.andrewchou.rnmapsissuerepro, PID: 17182
03-03 16:29:09.956 17182 17182 E AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.facebook.react.bridge.CxxCallbackImpl.invoke(java.lang.Object[])' on a null object reference
03-03 16:29:09.956 17182 17182 E AndroidRuntime: at com.rnmapbox.rnmbx.NativeRNMBXLocationModuleSpec.emitOnLocationUpdate(NativeRNMBXLocationModuleSpec.java:38)
03-03 16:29:09.956 17182 17182 E AndroidRuntime: at com.rnmapbox.rnmbx.modules.RNMBXLocationModule.access$emitOnLocationUpdate(RNMBXLocationModule.kt:18)
03-03 16:29:09.956 17182 17182 E AndroidRuntime: at com.rnmapbox.rnmbx.modules.RNMBXLocationModule$onUserLocationChangeCallback$1.onLocationChange(RNMBXLocationModule.kt:62)
03-03 16:29:09.956 17182 17182 E AndroidRuntime: at com.rnmapbox.rnmbx.location.LocationManager.onLocationChanged(LocationManager.kt:251)
03-03 16:29:09.956 17182 17182 E AndroidRuntime: at com.rnmapbox.rnmbx.location.LocationManager.onSuccess(LocationManager.kt:260)
03-03 16:29:09.956 17182 17182 E AndroidRuntime: at com.rnmapbox.rnmbx.location.LocationManager.onSuccess(LocationManager.kt:93)
03-03 16:29:09.956 17182 17182 E AndroidRuntime: at com.mapbox.android.core.location.LocationEngineCommonCompatKt$toCommonCompat$1.onSuccess(LocationEngineCommonCompat.kt:99)
03-03 16:29:09.956 17182 17182 E AndroidRuntime: at com.mapbox.android.core.location.LocationEngineCommonCompatKt$toCommonCompat$1.onSuccess(LocationEngineCommonCompat.kt:93)
03-03 16:29:09.956 17182 17182 E AndroidRuntime: at com.mapbox.common.location.compat.LocationEngineImpl$liveTrackingObserver$1$onLocationUpdateReceived$lambda-2$lambda-1$$inlined$postOrCall$1.run(LocationEngineImpl.kt:361)
03-03 16:29:09.956 17182 17182 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:938)
03-03 16:29:09.956 17182 17182 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
03-03 16:29:09.956 17182 17182 E AndroidRuntime: at android.os.Looper.loop(Looper.java:223)
03-03 16:29:09.956 17182 17182 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7656)
03-03 16:29:09.956 17182 17182 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
03-03 16:29:09.956 17182 17182 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
03-03 16:29:09.956 17182 17182 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Expected behavior
App should not crash when using a component that subscribes to location updates.
Notes / preliminary analysis
It's important to note that this seems to only be an issue when:
- The new arch is disabled. The issue is not present when the new arch is enabled
- Using
10.1.37of this library.10.1.36does NOT have this issue. - Using the
UserLocationcomponent. Guessing it's not necessarily only tied to that component but anything that may subscribe to location updates.
I can create a test repo if helpful, but hopefully this is enough to work with.
Additional links and references
No response
have the same issue
We have the same issue.
Same issue
Same issue
Same issue here
Same issue here. Any update?
@rnmapbox/maps v10.1.38
react-native v0.76.9
RNMapboxMapsVersion v11.9.2
newArch: false
ERROR TypeError: MapboxGLLocationManager.onLocationUpdate is not a function (it is undefined), js engine: hermes
@achou11 Would you please help me for this issue?
@achou11 Would you please help me for this issue?
@seyedmostafahasani I'm just a mere user 😄 Up to the maintainers to figure out how to address this.
Only thing I can suggest is pinning the version to a working version, which in my case was using 10.1.36
@achou11 I appreciate your time. I downgraded the version, but the issue still occurs.
@seyedmostafahasani Hi! I had the same issue — downgrading to version 10.1.36 fixed it. Make sure you’re using a strict version in your package.json (without the ^).
It should look like this: "@rnmapbox/maps": "10.1.36"
@Elter71 Cheers bud, explicit downgrade from 10.1.38 to 10.1.36 seems to sort for now.
We were definitely passing in a fn for onUpdate to the <Mapbox.UserLocation /> component FWIW.
expo: 52.0.46, rnmapbox/maps: 10.1.38 react-native: 0.76.9
TypeError: MapboxGLLocationManager.onLocationUpdate is not a function (it is undefined)
at LocationManager#start (our-app-path/node_modules/@rnmapbox/maps/src/modules/location/locationManager.ts:181:68)
at LocationManager#addListener (our-app-path/node_modules/@rnmapbox/maps/src/modules/location/locationManager.ts:125:16)
at setLocationManager (our-app-path/node_modules/@rnmapbox/maps/src/components/UserLocation.tsx:208:35)
at asyncGeneratorStep (our-app-path/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:23)
at _next (our-app-path/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:26)
...
(22 additional frame(s) were not displayed)
Same issue for me, downgrading to 10.1.36 made it working back
+1
I just downgraded to 10.1.36 as well, and it fixed the issue for me.
+1
Same issue on 10.1.39
+1
Have also encountered this issue.
Same issue but I fixed it
"@rnmapbox/maps": "10.1.39",
"react-native": "0.78.2",
old arch
Got it working by patching NativeRNMBXLocationModuleSpec.java
diff --git a/node_modules/@rnmapbox/maps/android/src/main/old-arch/com/rnmapbox/rnmbx/NativeRNMBXLocationModuleSpec.java b/node_modules/@rnmapbox/maps/android/src/main/old-arch/com/rnmapbox/rnmbx/NativeRNMBXLocationModuleSpec.java
index e5db5cb..43f40ae 100644
--- a/node_modules/@rnmapbox/maps/android/src/main/old-arch/com/rnmapbox/rnmbx/NativeRNMBXLocationModuleSpec.java
+++ b/node_modules/@rnmapbox/maps/android/src/main/old-arch/com/rnmapbox/rnmbx/NativeRNMBXLocationModuleSpec.java
@@ -19,12 +19,15 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReactModuleWithSpec;
import com.facebook.react.bridge.ReadableMap;
+import com.facebook.react.bridge.Callback;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import javax.annotation.Nonnull;
public abstract class NativeRNMBXLocationModuleSpec extends ReactContextBaseJavaModule implements ReactModuleWithSpec, TurboModule {
public static final String NAME = "RNMBXLocationModule";
+ protected Callback mEventEmitterCallback;
+
public NativeRNMBXLocationModuleSpec(ReactApplicationContext reactContext) {
super(reactContext);
}
@@ -35,7 +38,9 @@ public abstract class NativeRNMBXLocationModuleSpec extends ReactContextBaseJava
}
protected final void emitOnLocationUpdate(ReadableMap value) {
- mEventEmitterCallback.invoke("onLocationUpdate", value);
+ if (mEventEmitterCallback != null) {
+ mEventEmitterCallback.invoke("onLocationUpdate", value);
+ }
}
@ReactMethod
This is related to userLocation constantly listening to locationUpdate
if you are not going to move the user constantly on the map, "Mapbox.locationManager.stop();"
if you will move the user constantly on the map, use "Geolocation.watchPosition"
const watchId = useRef<number | null>(null);
watchId.current = Geolocation.watchPosition(pos => {
setuserLocation({
latitude: pos.coords.longitude,
longitude: pos.coords.latitude,
});
setCenterOfMap({
latitude: pos.coords.longitude,
longitude: pos.coords.latitude,
});
},
error => console.log('Error getting location:', error),
{ enableHighAccuracy: true, distanceFilter: 50 },);
return () => { Geolocation.clearWatch(watchId.current as number); };