Docs
Dashboard
HoneyNotify SDKs

Choose your platform

Select a platform to open its public SDK repository on GitHub.

AndroidKotlin and Firebase Cloud MessagingiOSSwift and Apple Push Notification serviceWebBrowser push and service worker support
Integration

SDK integration

HoneyNotify's iOS, Android, and web clients handle device registration, token refresh, user association, notification payload parsing, and engagement events. Give every client a restricted ps_public_ key—never a server send key.

Get the SDK source from GitHub:

Want to try HoneyNotify before building your own native shell? The ready-to-build demo apps provide configurable full-screen WebView projects for iOS and Android with registration, token refresh, notification-open handling, and lifecycle tracking already connected. Follow the demo apps guide for the complete setup path.

Common lifecycle#

Whichever platform you use, the durable integration pattern is:

  1. Ask for notification permission in context, after explaining the value.
  2. Obtain the provider token or browser Push subscription.
  3. Register it with HoneyNotify and retain the returned device ID.
  4. Identify after login, using a backend-issued identity token when verification is enabled.
  5. Refresh registration when provider tokens or audience attributes change.
  6. Parse notification data and track received/opened/clicked lifecycle events.
  7. Disable the device and clear local identity at logout or unsubscribe.

iOS 15+#

Add the Swift package from GitHub, initialise it once, and use your public client key.

import HoneyNotify

let honeyNotify = HoneyNotify(
    baseURL: URL(string: "https://api.honeynotify.com")!,
    clientKey: "ps_public_replace_me"
)

let granted = try await honeyNotify.requestPermissionAndRegister()

Only after Apple approves the host app's Critical Alerts entitlement, request the additional permission with requestPermissionAndRegister(includeCriticalAlerts: true). Use criticalAlertPermissionStatus() to inspect the user's current choice. HoneyNotify cannot grant this entitlement from the server or SDK.

Forward the APNs token from your application delegate:

func application(
    _ application: UIApplication,
    didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
    Task {
        _ = try await honeyNotify.register(
            deviceToken: deviceToken,
            tags: ["plan": "free"]
        )
    }
}

Use refresh(deviceToken:) for later APNs token changes. It preserves the external user ID and tags stored by the SDK.

After login:

_ = try await honeyNotify.identify(
    externalUserId: account.id,
    tags: ["plan": account.plan],
    identityToken: tokenFromYourBackend
)

In notification callbacks, use notification(from:), trackReceived(userInfo:), and trackOpened(userInfo:actionId:). For rich images, use HoneyNotifyMediaAttachment in a Notification Service Extension. Call logout() before clearing your app session if this device should stop receiving notifications for that user.

Android with Firebase#

Include the Android SDK source from GitHub in an application module configured for Firebase Messaging.

val honeyNotify = HoneyNotify(
    applicationContext,
    "https://api.honeynotify.com",
    "ps_public_replace_me"
)

honeyNotify.createNotificationChannels()

honeyNotify.registerCurrentToken(tags = mapOf("plan" to "free")) { result ->
    result.onFailure { error -> Log.e("Push", "Registration failed", error) }
}

Forward token refreshes from FirebaseMessagingService:

override fun onNewToken(token: String) {
    Thread { runCatching { honeyNotify.onTokenRefresh(token) } }.start()
}

Use the async helpers from UI-facing code:

honeyNotify.identifyAsync(
    externalUserId = account.id,
    tags = mapOf("plan" to account.plan),
    identityToken = tokenFromYourBackend
) { result ->
    result.onFailure { error -> Log.e("Push", "Identity failed", error) }
}

notificationFrom(data) extracts the notification ID, click URL, image URL, interruption level, channel ID, and data from FCM fields. Create the channels during foreground startup, before level-specific notifications arrive. Call trackReceived(data) when the message is received and trackOpened(data, actionId) from the user's interaction. Network methods such as register, identify, and logout are blocking; do not call them on the Android main thread. Android users can override every channel's importance and sound; HoneyNotify does not request full-screen intent or DND-policy access.

Web Push#

Download the web SDK from GitHub. Serve honeynotify-sw.js from your site root (or configure the matching service-worker path), then initialise the browser module:

import { HoneyNotify } from '/assets/honeynotify.js';

const honeyNotify = new HoneyNotify({
  baseURL: 'https://api.honeynotify.com',
  clientKey: 'ps_public_replace_me',
  vapidPublicKey: 'your_url_safe_vapid_public_key',
  serviceWorkerPath: '/honeynotify-sw.js',
});

const deviceId = await honeyNotify.requestPermissionAndRegister({
  externalUserId: currentUser?.id,
  identityToken: tokenFromYourBackend,
  tags: { plan: currentUser?.plan ?? 'visitor' },
});

The method returns null if permission is not granted. Browser permission prompts require a secure context and work best after a user gesture.

Track an application event:

await honeyNotify.track('checkout.abandoned', {
  metadata: { basket_id: 'basket_441' },
});

Call unsubscribe() to unsubscribe from the browser push service, disable the HoneyNotify device, and remove its local ID.

Identity token endpoint on your backend#

When identity verification is enabled, your authenticated backend should expose a small endpoint that returns a short-lived ES256 JWT for the current user. The private EC key must stay on the backend. The client requests a new token at login or identity refresh and passes it unchanged to the SDK.

Do not accept an arbitrary external user ID in that backend endpoint. Derive sub from the authenticated session, set iss to the HoneyNotify app public ID, and keep exp within one hour.

Testing checklist#

  • Test first permission grant, denial, and previously denied states.
  • Confirm registration returns the same logical device after token refresh.
  • Test anonymous use, login, account switching, and logout.
  • Confirm notification tap and action IDs reach your deep-link router.
  • Test foreground, background, and terminated app states.
  • Test missing images and expired deep links.
  • Confirm events appear under the intended notification and device.
  • Never use production users for broad-send tests; target an isolated test device or user.

Provider migration behaviour#

No special SDK call is required after an owner imports devices from a supported provider through the dashboard. The normal register or registerCurrentToken call sends the current APNs or FCM token. HoneyNotify checks the separate migration lookup for the same token and platform. On a match it claims the row and returns its assigned HoneyNotify device_id, which the SDK stores normally. UUID source IDs are retained; non-UUID source IDs receive a stable, provider-scoped HoneyNotify UUID. Without a match, registration behaves exactly like a new HoneyNotify installation and returns a newly generated HoneyNotify UUID.

For the highest automatic match rate, upload the provider export shortly before releasing the HoneyNotify-enabled app. Devices whose provider token changes between export and first HoneyNotify registration cannot be recognised from the token alone and receive a new HoneyNotify UUID.