capacitor-plugin-geofence
v0.0.2
Published
geofencing places
Readme
capacitor-plugin-geofence
geofencing places
Origin
This Capacitor plugin is based on the legacy cordova-plugin-geofence implementation and was migrated to Capacitor-native Android/iOS bridges.
Migration Notes (Cordova -> Capacitor)
initialize interface change
initializenow uses a structured permission result model.- Native Capacitor plugin interface (
GeofencePlugin) returns:initialize(): Promise<InitializeResult>
- Returned
InitializeResult:ready: booleanmissing: ("notification" | "location" | "background")[]requested: ("notification" | "location" | "background")[]granted: ("notification" | "location" | "background")[]
- Cordova-compatible JS facade (
Geofenceinsrc/index.ts) keeps callback-style usage and returnsPromise<boolean>:- returns
trueif permissions are already ready - returns
falsewhen async permission flow starts and final details are delivered in callback
- returns
function behavior changes
snooze(options: { id, duration })durationis interpreted in seconds- suppresses both transition callback (
transitionReceived) and notification delivery for the selected geofence during the active snooze window - snooze state is persisted on Android and iOS and survives app restart until expiration
Install
To use npm
npm install capacitor-plugin-geofenceTo use yarn
yarn add capacitor-plugin-geofenceSync native files
npx cap syncAPI
Integration Checklists
Compatibility
iOS
- Minimum supported iOS version:
15.0 - Configured in both:
Package.swift(platforms: [.iOS(.v15)])CapacitorPluginGeofence.podspec(s.ios.deployment_target = '15.0')
- Expected to work on current iOS major versions (15+), including recent releases.
Android
minSdkVersion:24targetSdkVersion:36compileSdk:36- Designed to be compatible with Android API
33+permission model:POST_NOTIFICATIONSruntime permission handling- foreground/background location permission separation
- geofencing
PendingIntentkept mutable where required by Play Services geofencing delivery
Behavior Notes
initialize
initialize(callback)is permission-focused (does not add/remove geofences)- Android and iOS use the same flow:
- notification permission (if missing)
- foreground location permission (if missing)
- if foreground location is still missing,
backgroundis also reported as missing and flow ends - background location permission is requested only after foreground is granted
- Callback result:
readymissingrequestedgranted
snooze
snooze({ id, duration })usesdurationin seconds- During active snooze window, both are suppressed for that geofence:
- transition callback (
transitionReceived) - notification display
- transition callback (
- Snooze state is persisted on both platforms and survives app restart until expiration.
How To Test
This plugin has native geofence behavior. Full validation requires a real device or emulator/simulator with location simulation.
What you can test without a device
- TypeScript build (
npm run build) - API wiring and compile-time checks
- Host app integration and sync (
npx cap sync)
What requires device/emulator
- Real geofence enter/exit transitions
- Background behavior
- Killed-app behavior
- Notification delivery and notification click callback
Recommended manual test flow
- Verify current state with
checkPermissionStatus - Start permission flow with
initialize(callback)initializereturnstrueif everything is already grantedinitializereturnsfalseif async permission flow started- Android and iOS now follow the same initialize sequence:
- request notification permission if needed
- request foreground location permission if needed
- if foreground is still missing,
backgroundis also reported missing and flow ends - request background location permission only after foreground is granted
- callback payload contains:
requested: ("notification" | "location" | "background")[]granted: ("notification" | "location" | "background")[]missing: ("notification" | "location" | "background")[]ready: boolean
- Add geofence:
addOrUpdate - Verify persistence API:
getWatched - Trigger location transition with real movement or mock route
- Verify:
transitionReceivedcallback- notification shown
notificationClickedcallback when tapped
- Validate cleanup:
remove/removeAlldismissNotifications
- Validate
snooze:- call
snooze({ id, duration })(duration in seconds) - during snooze window, transition callback/notification for that geofence is suppressed
- call
For platform-specific setup and edge-case validation, use:
checkPermissionStatus()requestLocationPermission()requestBackgroundLocationPermission()requestNotificationPermission()initialize()addOrUpdate(...)remove(...)removeAll()getWatched()dismissNotifications(...)snooze(...)deviceReady()ping()addListener('notificationClicked', ...)addListener('transitionReceived', ...)removeAllListeners()- Interfaces
- Type Aliases
checkPermissionStatus()
checkPermissionStatus() => Promise<Record<string, string>>Returns: Promise<Record<string, string>>
requestLocationPermission()
requestLocationPermission() => Promise<Record<string, string>>Returns: Promise<Record<string, string>>
requestBackgroundLocationPermission()
requestBackgroundLocationPermission() => Promise<Record<string, string>>Returns: Promise<Record<string, string>>
requestNotificationPermission()
requestNotificationPermission() => Promise<Record<string, string>>Returns: Promise<Record<string, string>>
initialize()
initialize() => Promise<InitializeResult>Returns: Promise<InitializeResult>
addOrUpdate(...)
addOrUpdate(options: AddOrUpdateOptions) => Promise<void>| Param | Type |
| ------------- | ----------------------------------------------------------------- |
| options | AddOrUpdateOptions |
remove(...)
remove(options: RemoveOptions) => Promise<void>| Param | Type |
| ------------- | ------------------------------------------------------- |
| options | RemoveOptions |
removeAll()
removeAll() => Promise<void>getWatched()
getWatched() => Promise<WatchedResult>Returns: Promise<WatchedResult>
dismissNotifications(...)
dismissNotifications(options: DismissNotificationsOptions) => Promise<void>| Param | Type |
| ------------- | ----------------------------------------------------------------------------------- |
| options | DismissNotificationsOptions |
snooze(...)
snooze(options: SnoozeOptions) => Promise<void>| Param | Type |
| ------------- | ------------------------------------------------------- |
| options | SnoozeOptions |
deviceReady()
deviceReady() => Promise<void>ping()
ping() => Promise<void>addListener('notificationClicked', ...)
addListener(eventName: 'notificationClicked', listenerFunc: (event: NotificationClickedEvent) => void) => Promise<PluginListenerHandle>| Param | Type |
| ------------------ | ------------------------------------------------------------------------------------------------- |
| eventName | 'notificationClicked' |
| listenerFunc | (event: NotificationClickedEvent) => void |
Returns: Promise<PluginListenerHandle>
addListener('transitionReceived', ...)
addListener(eventName: 'transitionReceived', listenerFunc: (event: TransitionReceivedEvent) => void) => Promise<PluginListenerHandle>| Param | Type |
| ------------------ | ----------------------------------------------------------------------------------------------- |
| eventName | 'transitionReceived' |
| listenerFunc | (event: TransitionReceivedEvent) => void |
Returns: Promise<PluginListenerHandle>
removeAllListeners()
removeAllListeners() => Promise<void>Interfaces
InitializeResult
| Prop | Type |
| --------------- | ------------------------------------ |
| ready | boolean |
| missing | InitMissingPermission[] |
| requested | InitMissingPermission[] |
| granted | InitMissingPermission[] |
AddOrUpdateOptions
| Prop | Type |
| --------------- | ----------------------- |
| geofences | Geofence[] |
Geofence
| Prop | Type |
| -------------------- | --------------------------------------------------------------------- |
| id | string |
| latitude | number |
| longitude | number |
| radius | number |
| transitionType | number |
| loiteringDelay | number |
| notification | GeofenceNotification |
| url | string |
| authorization | string |
| startTime | string |
| endTime | string |
GeofenceNotification
| Prop | Type |
| -------------------- | --------------------- |
| id | number |
| title | string |
| text | string |
| vibrate | number[] |
| icon | string |
| smallIcon | string |
| color | string |
| data | unknown |
| openAppOnClick | boolean |
| frequency | number |
| lastTriggered | number |
RemoveOptions
| Prop | Type |
| --------- | --------------------- |
| ids | string[] |
WatchedResult
| Prop | Type |
| --------------- | ----------------------- |
| geofences | Geofence[] |
DismissNotificationsOptions
| Prop | Type |
| --------- | --------------------- |
| ids | number[] |
SnoozeOptions
| Prop | Type |
| -------------- | ------------------- |
| id | string |
| duration | number |
PluginListenerHandle
| Prop | Type |
| ------------ | ----------------------------------------- |
| remove | () => Promise<void> |
NotificationClickedEvent
| Prop | Type |
| ---------- | -------------------- |
| data | unknown |
TransitionReceivedEvent
| Prop | Type |
| --------------- | ----------------------- |
| geofences | Geofence[] |
Type Aliases
Record
Construct a type with a set of properties K of type T
{ [P in K]: T; }
InitMissingPermission
'notification' | 'location' | 'background'
