capacitor-community / google-maps

Capacitor Plugin using native Google Maps SDK for Android and iOS.

Home Page:https://capacitor-community.github.io/google-maps/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

removeMarker does not work on iOS due to overly large marker `id` integer

patrick-entinux opened this issue · comments

Describe the bug

On iOS, Marker ID, which comes from hash value, may be a really large number like 3850296949834213376. This is too large to express safely as a JavaScript number and suffers data loss when passed through the capacitor bridge.

For didTap event, this is fine, because the data loss is the same as in the original addMarker function, so the marker can still be linked up by ID on the JavaScript side. However, for removeMarker method, as far as I can tell, it is basically impossible to use because our id in JavaScript needs to match the original id in the hashMap perfectly.

To Reproduce

(1) Run some code like below:

const result: { marker: { id: number } } =
  await CapacitorGoogleMaps.addMarker({
    latitude: marker.latitude,
    longitude: marker.longitude,
    title: marker.title,
  });
await CapacitorGoogleMaps.removeMarker({ id: result.marker.id });

(2) Observe that the marker is not deleted

Expected behavior

The marker should be deleted.

Screenshots

Demonstration of MAX_SAFE_INTEGER in JavaScript and data loss between input and output for an integer like 3850296949834213376:

image

Demonstration of input value to removeMarker function (as parsed inside the native code side) compared to the list of all values in the hashMap:

Screen Shot 2022-02-15 at 13 44 33

Additional context

One super basic workaround could be to pass marker ids as string, starting with the prefix m, similar to the Android side of the plugin (which appears to use a string starting with m):

var hashMap = [String : GMSMarker]();

...

                let id = "m\(marker.hash.hashValue)"

                // get auto-generated id of the just added marker,
                // put this marker into a hashmap with the corresponding id,
                // so we can retrieve the marker by id later on
                self.hashMap[id] = marker;
              
                NSLog("addMarker \(id)")

                call.resolve([
                    "markerAdded": true,
                    // get marker specific values
                    "marker": [
                        "id": id
                    ]
                ])

...

    public func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
        self.notifyListeners("didTap", data: ["result": [
            "coordinates": [
                "latitude": marker.position.latitude,
                "longitude": marker.position.longitude
            ],
            "id": "m\(marker.hash.hashValue)",
            "title": marker.title ?? "",
            "snippet": marker.snippet ?? "",
            "metadata": marker.userData
        ]])
        return false
    }
commented

We've just released a (pretty stable) beta for version 2 of this plugin under the name @capacitor-community/google-maps.

It features a more complete and consistent API. Also the map can finally be rendered behind the webview in this new version.

Extensive documentation for v2 can be found here: https://capacitor-community.github.io/google-maps/

Since version 1 lacked a lot of (basic) features, did not have good coding practices, had a poor API and it is not recommended to use it anymore, we've dropped support for it. Therefore I will close this issue. We believe version 2 offers a better Developer Experience and is a much better fit for anyones use case.