Skip to content

[google_maps_flutter] Add onPointOfInterestTap callback - #11872

Open
tenninebt wants to merge 2 commits into
flutter:mainfrom
tenninebt:google-maps-on-poi-tap
Open

[google_maps_flutter] Add onPointOfInterestTap callback#11872
tenninebt wants to merge 2 commits into
flutter:mainfrom
tenninebt:google-maps-on-poi-tap

Conversation

@tenninebt

@tenninebt tenninebt commented Jun 8, 2026

Copy link
Copy Markdown

Adds GoogleMap.onPointOfInterestTap, a callback that fires when the user taps a built-in map point of interest. The callback receives a PointOfInterestId containing the place ID only, matching maintainer feedback on #4052 and #10963.

The change is wired through the federated plugin stack: platform_interface (type + event stream), Android (OnPoiClickListener), iOS including sdk9/sdk10/shared (didTapPOIWithPlaceID), web (IconMouseEvent.placeId on map click), and the app-facing google_maps_flutter package. Tests cover Dart unit tests, Android Robolectric, iOS native, and web integration tests in the web example.

Fixes flutter/flutter#60695

Pre-Review Checklist

@tenninebt
tenninebt force-pushed the google-maps-on-poi-tap branch 9 times, most recently from 336fb13 to e125948 Compare June 13, 2026 07:30
@tenninebt
tenninebt marked this pull request as ready for review June 13, 2026 07:31

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds support for tapping points of interest (POIs) on the map across Android, iOS, and Web platforms in the google_maps_flutter plugin. It introduces the PointOfInterestId type and PointOfInterestTapEvent in the platform interface, exposes the onPointOfInterestTap callback on the GoogleMap widget, and implements the platform-specific event handling and Pigeon messaging. The review feedback suggests adding a defensive null check for the PointOfInterest parameter in the Android onPoiClick handler to prevent a potential NullPointerException.

Comment on lines +390 to +395
public void onPoiClick(PointOfInterest pointOfInterest) {
if (pointOfInterest.placeId != null) {
flutterApi.onPointOfInterestTap(
pointOfInterest.placeId, (Result<Unit> result) -> Unit.INSTANCE);
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Defensively checking pointOfInterest for null before accessing its properties is a good practice to prevent potential NullPointerExceptions, especially since the parameter is not annotated with @NonNull.

Suggested change
public void onPoiClick(PointOfInterest pointOfInterest) {
if (pointOfInterest.placeId != null) {
flutterApi.onPointOfInterestTap(
pointOfInterest.placeId, (Result<Unit> result) -> Unit.INSTANCE);
}
}
public void onPoiClick(PointOfInterest pointOfInterest) {
if (pointOfInterest != null && pointOfInterest.placeId != null) {
flutterApi.onPointOfInterestTap(
pointOfInterest.placeId, (Result<Unit> result) -> Unit.INSTANCE);
}
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The placeId null guard is the important part, and it’s already there. The Maps SDK only calls onPoiClick with a non-null PointOfInterest when a POI is tapped, and the other click handlers in this class don’t null-check their parameters either. We already have a test for the realistic case (placeId == null), which matches iOS. An extra pointOfInterest != null check would be harmless but unnecessary.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough.

@stuartmorgan-g
stuartmorgan-g self-requested a review June 23, 2026 18:26
@tenninebt

Copy link
Copy Markdown
Author

Hi @stuartmorgan-g when you're ready to review ping me and I'll do it right away. I'd rather fix the conflicts onces and for all instead of doing it every commit on that part of the code ;).

@stuartmorgan-g

stuartmorgan-g commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

No need to resolve changelog/pubspec comments until the whole review process is essentially complete (per the FAQ) since the conflicts in those files don't affect the ability to review the changes.

Comment thread packages/google_maps_flutter/google_maps_flutter/example/lib/map_click.dart Outdated
Comment thread packages/google_maps_flutter/google_maps_flutter/pubspec.yaml
- (void)didLongPressAtPosition:(FGMPlatformLatLng *)position;

/// Called when a point of interest is tapped.
- (void)didTapPointOfInterestWithPlaceId:(NSString *)placeId;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...WithPlaceIdentifier:

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed. I also moved the declaration up so it sits in the same spot as the matching method in MapsCallbackApi.

void onCircleTap(String circleId);

/// Called when a point of interest is tapped.
@ObjCSelector('didTapPointOfInterestWithPlaceId:')

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...PlaceIdentifier:

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, it's didTapPointOfInterestWithPlaceIdentifier: now.

@tenninebt
tenninebt force-pushed the google-maps-on-poi-tap branch 3 times, most recently from 1a982ab to 2247d7a Compare July 30, 2026 16:22
Expose a place-ID-only POI tap stream across the federated plugin stack
(Android, iOS, web) so apps can react when users tap built-in map POIs.

Fixes flutter/flutter#60695
@tenninebt
tenninebt force-pushed the google-maps-on-poi-tap branch from 2247d7a to 1215581 Compare July 30, 2026 16:33
@tenninebt
tenninebt requested a review from stuartmorgan-g July 30, 2026 16:36
@stuartmorgan-g stuartmorgan-g added triage-ios Should be looked at in iOS triage triage-android Should be looked at in Android triage labels Aug 10, 2026
@stuartmorgan-g stuartmorgan-g added federated: all_changes PR that contains changes for all packages for a federated plugin change triage-web Should be looked at in web triage labels Aug 10, 2026
@stuartmorgan-g
stuartmorgan-g requested a review from mdebbar August 10, 2026 16:49

@stuartmorgan-g stuartmorgan-g left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good structurally; passing off to platform teams for in-depth platform-level reviews.

One question about the web implementation though.


/// Fake implementation of FGMMapsCallbackApiProtocol that records the calls it receives.
class MockMapsCallbackApi: NSObject, FGMMapsCallbackApiProtocol {
var lastTappedPointOfInterestPlaceIdentifier: String?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Longer term this object may need to take callbacks instead of recording values, to allow for more flexible tests, but this is probably fine for now.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point — I'll keep that in mind if we need more flexible tests down the line. Leaving it as-is for now since it covers what we need.

import 'dart:async';
import 'dart:convert';
import 'dart:js_interop';
import 'dart:js_interop_unsafe';

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this? Is there a property that needs to be added to google_maps? If so, that should be done upstream rather than worked around here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. The placeId property should be added upstream. Or defined here using normal JS interop:

extension PlaceIdExtension on gmaps.MapMouseEventOrIconMouseEvent {
  external String? placeId;
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, we don't need unsafe interop here. I added a local placeId extension on MapMouseEventOrIconMouseEvent (same approach @mdebbar suggested) and read that directly in the click handler. Upstream would still be cleaner long term, but this gets us off dart:js_interop_unsafe for now.

@stuartmorgan-g stuartmorgan-g added the CICD Run CI/CD label Aug 10, 2026

@mdebbar mdebbar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Web changes look good to me but we should try to eliminate the use of dart:js_interop_unsafe.

import 'dart:async';
import 'dart:convert';
import 'dart:js_interop';
import 'dart:js_interop_unsafe';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. The placeId property should be added upstream. Or defined here using normal JS interop:

extension PlaceIdExtension on gmaps.MapMouseEventOrIconMouseEvent {
  external String? placeId;
}

@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Aug 24, 2026

@vashworth vashworth left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iOS side LGTM

@reidbaker
reidbaker requested review from a team and camsim99 and removed request for a team and reidbaker August 27, 2026 19:58

@camsim99 camsim99 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Android implementation LGTM!

Comment on lines +390 to +395
public void onPoiClick(PointOfInterest pointOfInterest) {
if (pointOfInterest.placeId != null) {
flutterApi.onPointOfInterestTap(
pointOfInterest.placeId, (Result<Unit> result) -> Unit.INSTANCE);
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough.

@mdebbar mdebbar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Web changes look good!

@stuartmorgan-g

Copy link
Copy Markdown
Collaborator

Now that this has all the platform team sign-offs, please go ahead and make the first sub-PR with the platform interface changes.

@tenninebt

Copy link
Copy Markdown
Author

Opened the platform interface sub-PR as requested: #12752

@tenninebt
tenninebt force-pushed the google-maps-on-poi-tap branch from c023adc to 62ef656 Compare September 4, 2026 16:05
…safe

MapMouseEventOrIconMouseEvent only exposes latLng upstream, so add a
local external placeId getter and use that in the click handler instead
of hasProperty + cast.
@tenninebt
tenninebt force-pushed the google-maps-on-poi-tap branch from 62ef656 to 954c841 Compare September 4, 2026 16:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

federated: all_changes PR that contains changes for all packages for a federated plugin change p: google_maps_flutter platform-android platform-ios platform-web triage-android Should be looked at in Android triage triage-ios Should be looked at in iOS triage triage-web Should be looked at in web triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[google_maps_flutter] Add callback for click on google poi's on the map

5 participants