googlemaps / googlemaps/react-native-navigation-sdk

[Bug]: (int) prefrerredHeading case

Aperta
#654 1 commento 0 reazioni 1 assegnatario Rivendicata da @jokerttu Vedi su GitHub
triage me type: bug
Lingua principale
TypeScript
Stelle
227
Fork
38
Merge medio
5g 7h
PR unite (30g)
10

Descrizione

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Description of the bug

Repo: https://github.com/googlemaps/react-native-navigation-sdk/issues/new

Title: Android: `setDestinations` throws ClassCastException when a waypoint sets `preferredHeading` (Double cast to Integer)

## Environment
- `@googlemaps/react-native-navigation-sdk` 0.16.3 (the cast is unchanged on `main` at 036c83e, 2026-09-07)
- React Native 0.86, Expo SDK 57, new architecture
- Android (Samsung, Android 15); iOS is unaffected

## Steps
```ts
await navigationController.setDestinations(
[
{ title: 'Entry', position: { lat: 42.27853, lng: -83.67608 }, preferredHeading: 0 },
{ title: 'Destination', position: { lat: 42.32438, lng: -83.62626 } },
],
{ routingOptions: { travelMode: TravelMode.DRIVING } },
);
```

## Expected
The route is computed with the heading preference applied to the first waypoint (as on iOS).

## Actual
The promise rejects before the SDK is called:
```
Exception in HostFunction: java.lang.Double cannot be cast to java.lang.Integer
at com.google.android.react.navsdk.NavModule.createWaypoint(NavModule.java:571)
at com.google.android.react.navsdk.NavModule.setDestinations(NavModule.java:604)
```

## Cause
`NavModule.createWaypoint` casts the raw map value:
```java
if (map.containsKey("preferredHeading")) {
int preferredHeading = (int) map.get("preferredHeading"); // line 571
waypointBuilder.setPreferredHeading(preferredHeading);
}
```
Every JS number crosses the bridge as a `java.lang.Double`, so the `(int)` cast throws. The same file already handles this correctly two lines earlier for `travelMode` via `CollectionUtil.getInt`, which does `((Double) map.get(name)).intValue()`.

## Fix (one line)
```java
if (map.containsKey("preferredHeading")) {
int preferredHeading = CollectionUtil.getInt("preferredHeading", map, 0);
waypointBuilder.setPreferredHeading(preferredHeading);
}
```
Happy to open a PR if that is welcome.

## Workaround
Omit `preferredHeading` on Android (`Platform.OS === 'android'`), which loses the side-of-road hint there.

### iOS Platform

Not affected

### Android Platform

Affected

### React Native version

0.86.2

### React version

19.2.3

### Package version

wrapper 0.16.3 with its stock native pins, Navigation SDK for iOS 10.13.0 and for Android 7.6.1.

### Native SDK versions

- [x] I haven't changed the version of the native SDKs

### React Native Doctor Output

Common
✓ Node.js - Required to execute JavaScript code
✓ yarn - Required to install NPM dependencies
✓ npm - Required to install NPM dependencies
● Watchman - Used for watching changes in the filesystem when in development mode
● Metro - Metro Bundler is not running

Android
✖ Adb - No devices and/or emulators connected. Please create emulator with Android Studio or connect Android device.
✓ JDK - Required to compile Java code
✓ Android Studio - Required for building and installing your app on Android
✓ ANDROID_HOME - Environment variable that points to your Android SDK installation
✖ Gradlew - Build tool required for Android builds
✖ Android SDK - Required for building and installing your app on Android
- Versions found: 30.0.3, 33.0.2, 34.0.0, 34.0.0, 35.0.0, 36.0.0
- Version supported: Not Found

iOS
✓ Xcode - Required for building and installing your app on iOS
✓ Ruby
✖ CocoaPods - Required for installing iOS dependencies
- Version found: N/A
- Version supported: >= 1.10.0
✓ .xcode.env - File to customize Xcode environment

Errors: 4
Warnings: 2

Expo SDK 57 managed project, native builds on EAS; no local android/ or ios/ checkout, hence Gradlew and CocoaPods missing and no supported SDK version detected. The Samsung device was disconnected when this ran.

### Steps to reproduce

1. Install @googlemaps/react-native-navigation-sdk 0.16.3 in a React Native 0.86 app (new architecture) and run it on an Android device. iOS is not needed; it is unaffected.
2. Initialize navigation as usual: NavigationView mounted, terms accepted, navigationController.init() returned OK, and a location fix has arrived.
3. Call setDestinations with any waypoint that sets preferredHeading, for example:
await navigationController.setDestinations(
[
{ title: 'Entry', position: { lat: 42.27853, lng: -83.67608 }, preferredHeading: 0 },
{ title: 'Destination', position: { lat: 42.32438, lng: -83.62626 } },
],
{ routingOptions: { travelMode: TravelMode.DRIVING } },
);
4. Observe: the promise rejects immediately, before the native SDK computes a route:
Exception in HostFunction: java.lang.Double cannot be cast to java.lang.Integer
at com.google.android.react.navsdk.NavModule.createWaypoint(NavModule.java:571)
at com.google.android.react.navsdk.NavModule.setDestinations(NavModule.java:604)
Any value reproduces it, including 0, 12, and 12.0, because the JS number always arrives as a java.lang.Double.
5. Remove preferredHeading from the waypoint and call again: the route is computed and guidance starts. The same waypoint with preferredHeading works on iOS.

### Expected vs Actual Behavior

The route is computed with the heading preference applied to the first waypoint (as on iOS).

### Code Sample

```javascript
if (map.containsKey("preferredHeading")) {
int preferredHeading = CollectionUtil.getInt("preferredHeading", map, 0);
waypointBuilder.setPreferredHeading(preferredHeading);
}
```

### Additional Context

_No response_

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.