Skip to content

fix: detect missing Maps API key up front in Android Street View - #401

Merged
gdoumen merged 3 commits into
mainfrom
feat/fix-streetview-missing-key
Aug 19, 2026
Merged

fix: detect missing Maps API key up front in Android Street View#401
gdoumen merged 3 commits into
mainfrom
feat/fix-streetview-missing-key

Conversation

@gdoumen

@gdoumen gdoumen commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes FIXES_BACKLOG item #59. Android Street View now detects a missing Maps API key immediately instead of hanging for 12+ seconds on a generic timeout.

Changes

  • StreetViewManager.kt: Check apiKeyState(context) at the start of createViewInstance, before any view lifecycle methods or emitLicenseConsumed. If the key is missing or unreadable, emit an onError with reason "apiKeyMissing" and return early, skipping the billable onCreate() call and the permanent getStreetViewPanoramaAsync wait.

  • types.ts: Add "apiKeyMissing" to the StreetViewErrorReason union type.

  • RidePage/GPX/View.tsx: Add onSVError handler that treats apiKeyMissing as a hard/permanent failure. Unlike transient timeouts (unavailable/unknown), this error is passed to the service layer as a mapStateError to be shown in the start overlay as a dead end.

  • StreetViewDemoPage.tsx: Distinguish apiKeyMissing from transient errors in the demo's status display.

Implementation notes

  • The Kotlin code constructs a StreetViewPanoramaView instance (the return type requires it) but does not call onCreate(), onResume(), or emitLicenseConsumed when the key is missing. Per Google's documentation, this avoids the billable event.
  • The error is emitted before the view has a React tag, so it is buffered in PanoramaState and flushed from onAfterUpdateTransaction like diagnostic logs.
  • Manual validation on a real Android device with MAPS_API_KEY unset is pending to confirm no Street View panorama instantiation is logged in Google Cloud Console.

Test plan

  • Manually test on Android device with MAPS_API_KEY unset: error should be immediate (no 12s wait), message should be clear
  • Verify no Street View event appears in Google Cloud Console billing when key is missing
  • Confirm StreetViewDemo page shows FATAL status for apiKeyMissing error

Checklist

  • Changes compile (no new TypeScript/Kotlin errors)
  • Manual validation on real Android device pending
  • Ready for review

FIXES_BACKLOG #59: Missing API key is now detected before view construction, preventing
a billable Street View event and immediate hard error instead of 12s timeout.

- StreetViewManager.kt: Check apiKeyState() before onCreate()/onResume(), emit "apiKeyMissing"
  error instead of generic timeout when key is missing/unreadable. Skips license-consumed event.
- types.ts: Add "apiKeyMissing" to StreetViewErrorReason union
- RidePage/GPX/View.tsx: Add onSVError handler that treats apiKeyMissing as hard failure,
  passes to service layer as mapStateError
- StreetViewDemoPage.tsx: Distinguish hard "apiKeyMissing" errors from transient timeouts

Manual validation on real Android device with MAPS_API_KEY unset pending.
Extends #59's Android fix to iOS for consistency. iOS's ensurePanorama already
avoided the billable GMSPanoramaView allocation and reported a fast onError
when the key was missing (no 12s-hang bug on this platform), but used the
generic 'unknown' reason shared with other SDK-never-engaged failures. JS
consumers (RidePage/GPX/View.tsx, StreetViewDemoPage) now special-case
'apiKeyMissing' as a hard/permanent failure, so iOS needs to emit the same
distinguishable reason for a confirmed-missing key. Every other 'unknown'
case (provideAPIKey: returning false/throwing) is untouched.
…s a React tag

createViewInstance's apiKeyMissing early-return called emitError from the exact
untagged window where emitLog/emitLicenseConsumed already buffer via PanoramaState
(flushed later from onAfterUpdateTransaction) — emitError had no such buffering, so
emitEvent silently dropped the event (view.context as ThemedReactContext resolves
fine but UIManagerHelper.getEventDispatcherForReactTag needs a real tag). The
pre-existing ready-timeout emitError('unknown') call never hit this because it
fires from a postDelayed callback, by which time the view normally already has
its tag.

Confirmed via real device log on PR #401: the apiKeyMissing billing fix worked
(no license-consumed event), but JS never learned about it and fell through to
the old 15s generic timeout + indefinite retry.

Gives emitError the same buffer-and-flush treatment as emitLicenseConsumed:
PanoramaState.pendingError holds the payload (not just a flag, since the error
carries a reason string), emitError buffers into it when view.id == View.NO_ID,
and flushPendingLogs flushes it alongside the existing logs-then-license flush.
@sonarqubecloud

Copy link
Copy Markdown

@gdoumen
gdoumen marked this pull request as ready for review August 19, 2026 11:59
@gdoumen
gdoumen merged commit bbaf101 into main Aug 19, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant