B Bubbl Docs

SDK API Reference

This page lists the SDK calls most apps use after installing Bubbl. Names vary slightly by platform, but the integration flow is the same: boot the SDK, forward permissions and push data from your app, pass location updates when needed, then use diagnostics and events to confirm behavior.

Only use APIs exposed by the SDK package version installed in your app. If a method is not present in your installed 4.0.2 package, do not rely on it in a live release.

Required vs optional

Every integration needs:

  • apiKey
  • boot(config)
  • A live environment value in the platform quickstart
  • Push token forwarding if the app uses Bubbl notifications
  • Location permission and location updates if the app uses geofences
  • diagnostics() during verification

Most integrations also use:

  • segments or updateSegments(tags) for campaign eligibility
  • correlationId or setCorrelationId(id) for matching Bubbl activity to your app journey
  • flush() after important verification steps

Optional features:

  • SDK-managed location tracking
  • Default Bubbl notification modal and survey UI
  • Host-rendered notification UI
  • Custom modal colors and corner radius
  • Custom app events through track(event)

Configuration

Option Required Description
apiKey Yes Your live Bubbl SDK API key.
environment Yes Set this to the live Bubbl environment value shown in your platform quickstart.
segments No Segment tags for campaign eligibility. Set at boot and update when the user's eligibility changes.
correlationId No Your app's user, session, order, journey, visit, or job reference. Avoid values that expose unnecessary personal data.
defaultDistanceMeters No Default distance used where campaign/location distance is not supplied.
refreshIntervalSeconds No Minimum refresh interval for SDK-managed refreshes.
enablePushHandling No Enables Bubbl push payload handling. Leave on for most notification integrations.
enableLocationTracking No Lets the SDK manage location tracking. Leave off if your app already owns location collection.
notificationRenderingMode No Choose SDK default, host-rendered, or event-only notification behavior.
enableDefaultNotificationModal No Allows the SDK default notification detail modal.
defaultNotificationModalStyle No Sets supported default modal colors and corner radius.
enableDefaultSurveyUi No Allows the SDK default survey UI.
allowGeofenceRetriggers No Allows the same geofence campaign to trigger again when campaign rules permit it. Leave enabled unless your product needs one trigger per qualifying visit.
enableGeofenceDebugEvents No Emits extra geofence evaluation events during integration testing. Keep disabled in normal production builds.
logLevel No SDK log verbosity. Use a quieter level in production builds.

Only set custom endpoint URLs if Bubbl support asks you to.

Common option values

Environment values:

Platform Production value
Android BubblEnvironment.Production
iOS .production
Flutter BubblEnvironment.production
React Native 'production'

Notification rendering values:

Platform SDK default Host rendered Event only
Android BubblNotificationRenderingMode.SdkDefault BubblNotificationRenderingMode.HostRendered BubblNotificationRenderingMode.EventOnly
iOS .sdkDefault .hostRendered .eventOnly
Flutter BubblNotificationRenderingMode.sdkDefault BubblNotificationRenderingMode.hostRendered BubblNotificationRenderingMode.eventOnly
React Native 'sdkDefault' 'hostRendered' 'eventOnly'

Use sdkDefault when you want Bubbl to render notification details and surveys. Use hostRendered when your app renders the notification UI but still forwards actions back to Bubbl. Use eventOnly when your app only wants parsed events and will own all presentation.

Boot examples

Boot once during app startup, after your app configuration is available. Keep the API key in app configuration rather than reusable library code.

Android:

BubblSdk.install(applicationContext)

val result = BubblSdk.boot(
    BubblConfig(
        apiKey = BuildConfig.BUBBL_API_KEY,
        environment = BubblEnvironment.Production,
        segments = listOf("loyalty-member"),
        correlationId = currentVisitId,
        enablePushHandling = true,
        enableLocationTracking = false
    )
)

iOS:

let result = try await BubblClient.shared.boot(
    BubblConfig(
        apiKey: bubblApiKey,
        environment: .production,
        segments: ["loyalty-member"],
        correlationId: currentVisitId,
        enablePushHandling: true,
        enableLocationTracking: false
    )
)

Flutter:

final result = await BubblSdk.instance.boot(
  const BubblConfig(
    apiKey: String.fromEnvironment('BUBBL_API_KEY'),
    environment: BubblEnvironment.production,
    segments: ['loyalty-member'],
    enablePushHandling: true,
    enableLocationTracking: false,
  ),
);

React Native:

const result = await Bubbl.boot({
  apiKey: Config.BUBBL_API_KEY,
  environment: 'production',
  segments: ['loyalty-member'],
  correlationId: currentVisitId,
  enablePushHandling: true,
  enableLocationTracking: false,
});

After boot, check result.ready, result.requiresPermission, and result.warnings if your platform exposes them.

Common methods

Method Required Use it when
boot(config) Yes Starting the SDK with your API key and settings.
shutdown() No Stopping SDK activity for the current app process, usually during sign-out or teardown.
refresh() No Refreshing SDK configuration and push-related campaign state.
getConfiguration() No Reading the current campaign/config summary.
getPrivacyText() No Displaying privacy text supplied by Bubbl configuration.
startLocationTracking() Conditional Letting the SDK manage location tracking after the user grants permission.
stopLocationTracking() Conditional Stopping SDK-managed location tracking.
handleLocationUpdate(location) Conditional Passing an app-managed location update to Bubbl.
refreshGeofence(location) Conditional Fetching and evaluating geofence campaign state for a known location.
refreshPush() Conditional Refreshing push-related campaign state.
registerPushToken(token) Conditional Sending the current FCM/APNs token to Bubbl.
handleFirebasePayload(payload) Conditional Letting Bubbl parse a Firebase data payload.
showNotification(payload) No Asking Bubbl to display a notification payload with SDK UI.
handleNotificationPayload(payload) No Recording receipt and applying the configured rendering mode.
handleNotificationOpen(payload, action) No Telling Bubbl the user opened a notification in host-rendered UI.
openNotificationModal(payload) No Opening the SDK default detail modal from your own notification list or inbox.
handleNotificationCta(payload, action) No Telling Bubbl the user tapped a CTA in host-rendered UI.
handleNotificationMediaViewed(payload) No Telling Bubbl the user viewed campaign media in host-rendered UI.
handleNotificationSurveyRequested(payload) No Telling Bubbl the user opened a survey from host-rendered UI.
updateSegments(tags) No Replacing current segment tags after sign-in, profile, tier, or journey changes.
setCorrelationId(id) No Setting the current app user, session, visit, journey, order, or job reference.
clearCorrelationId() No Removing the current correlation ID, usually at sign-out or journey end.
track(event) No Tracking a supported custom SDK event.
submitSurveyResponse(response) Conditional Sending a survey response from custom UI.
flush() No Asking the SDK to send queued events now.
diagnostics() Yes for verification Returning SDK health and setup details.

Method recipes

Use these recipes as a quick map from app workflow to SDK calls.

App workflow Calls
App starts and the user is eligible for Bubbl content boot(config), then diagnostics() during verification.
User signs in or their profile changes updateSegments(tags) and setCorrelationId(id) if you have a current app journey reference.
User signs out clearCorrelationId(), replace segments with the next valid set, and optionally flush().
Firebase/APNs returns a new token registerPushToken(token).
Foreground push message arrives handleFirebasePayload(data), then render according to your chosen mode.
User opens your own notification card handleNotificationOpen(payload, action).
User taps a CTA in your own UI handleNotificationCta(payload, action), then navigate in your app.
User views campaign media in your own UI handleNotificationMediaViewed(payload).
User opens a custom survey handleNotificationSurveyRequested(payload).
User submits a custom survey submitSurveyResponse(response), then flush() if you need immediate verification.
App already has a location update handleLocationUpdate(location).
App wants immediate geofence evaluation refreshGeofence(location).
QA/support evidence is needed diagnostics(), then flush().

Push token and payload forwarding

Register the latest push token whenever Firebase/APNs gives one to your app.

Android:

override fun onNewToken(token: String) {
    scope.launch {
        BubblSdk.registerPushToken(token)
    }
}

iOS:

func application(
    _ application: UIApplication,
    didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
    Task {
        try? await BubblClient.shared.updateAPNsToken(deviceToken)
    }
}

Flutter:

final token = await FirebaseMessaging.instance.getToken();
if (token != null) {
  await BubblSdk.instance.registerPushToken(token);
}

React Native:

const token = await messaging().getToken();
await Bubbl.registerPushToken(token);

Forward Firebase data payloads to the SDK. handleFirebasePayload returns a parsed Bubbl notification payload when the message contains Bubbl notification data, or null when it does not.

Flutter:

FirebaseMessaging.onMessage.listen((message) async {
  final payload = await BubblSdk.instance.handleFirebasePayload(message.data);
  if (payload != null) {
    debugPrint('Bubbl notification received: ${payload.id}');
  }
});

If your app has separate foreground, background, and tap handlers, forward the same Bubbl data payload in each path. The platform-specific push libraries decide which handler runs; Bubbl only sees messages that your app forwards.

React Native:

messaging().onMessage(async message => {
  const data = Object.fromEntries(
    Object.entries(message.data ?? {}).map(([key, value]) => [key, String(value)]),
  );
  const payload = await Bubbl.handleFirebasePayload(data);
  if (payload) {
    console.log('Bubbl notification received', payload.id);
  }
});

Location and geofence patterns

If your app already collects location, pass location updates to Bubbl:

BubblSdk.handleLocationUpdate(
    BubblLocation(latitude = 51.5072, longitude = -0.1276)
)
await BubblSdk.instance.handleLocationUpdate(
  const BubblLocation(latitude: 51.5072, longitude: -0.1276),
);
await Bubbl.handleLocationUpdate({
  latitude: 51.5072,
  longitude: -0.1276,
});

If you want the SDK to manage location tracking, request the correct platform permission first, then start tracking:

BubblSdk.startLocationTracking()
await BubblSdk.instance.startLocationTracking();
await Bubbl.startLocationTracking();

Use refreshGeofence(location) when you want to evaluate a known location immediately. It does not return a geofence snapshot directly; observe SDK events, diagnostics, and logs to verify results.

Geofence trigger behavior

Campaign timing rules are managed in Bubbl. The SDK evaluates device movement and applies the campaign rules it receives. In most apps, keep allowGeofenceRetriggers enabled so dashboard campaign timing controls repeat behavior. Disable it only when your app deliberately wants to suppress repeated geofence candidates on the device.

During QA, enableGeofenceDebugEvents can help you see enter, exit, dispatch, and suppression events in the SDK event stream. Turn it off before general release unless Bubbl support asks you to keep it enabled for a short investigation.

Segments and correlation IDs

Use segments for eligibility and correlation IDs for your own references.

BubblSdk.updateSegments(listOf("gold-member", "store-visitor"))
BubblSdk.setCorrelationId("visit_12345")
try await BubblClient.shared.updateSegments(["gold-member", "store-visitor"])
try await BubblClient.shared.setCorrelationId("visit_12345")
await BubblSdk.instance.updateSegments(['gold-member', 'store-visitor']);
await BubblSdk.instance.setCorrelationId('visit_12345');
await Bubbl.updateSegments(['gold-member', 'store-visitor']);
await Bubbl.setCorrelationId('visit_12345');

At sign-out or journey end, clear the correlation ID and replace segments with the next valid set for the device:

BubblSdk.clearCorrelationId()
BubblSdk.updateSegments(emptyList())

Do not put email addresses, phone numbers, or raw names in segment tags or correlation IDs. Use stable app references such as a visit ID, order ID, booking ID, loyalty tier, or product journey state.

Custom event examples

Use track(event) for supported app milestones that should be visible to Bubbl. Keep events small and tied to a user action or journey state.

Flutter:

await BubblSdk.instance.track(
  const BubblTrackEvent(
    type: 'journey',
    activity: 'booking_confirmed',
    locationId: 'store-123',
  ),
);

React Native:

await Bubbl.track({
  type: 'journey',
  activity: 'booking_confirmed',
  locationId: 'store-123',
});

Android:

BubblSdk.track(
    BubblTrackEvent(
        type = "journey",
        activity = "booking_confirmed",
        locationId = "store-123"
    )
)

iOS:

try await BubblClient.shared.track(
    BubblTrackEvent(
        type: "journey",
        activity: "booking_confirmed",
        locationId: "store-123"
    )
)

Notification and survey handling

For SDK-rendered notifications, let handleFirebasePayload or handleNotificationPayload process the payload and use your configured rendering mode.

For host-rendered UI, parse the payload and forward user actions back to Bubbl:

const payload = await Bubbl.handleFirebasePayload(data);

if (payload) {
  renderYourNotificationCard(payload);
}

await Bubbl.handleNotificationOpen(payload, 'card_opened');

if (payload.cta?.label) {
  await Bubbl.handleNotificationCta(payload, payload.cta.action ?? 'primary_cta');
}

if (payload.media) {
  await Bubbl.handleNotificationMediaViewed(payload);
}

Submit survey responses only after the user completes your survey UI:

await BubblSdk.instance.submitSurveyResponse(
  BubblSurveyResponse(
    curatedNotificationId: payload.curatedNotificationId!,
    locationId: payload.locationId,
    answers: [
      BubblSurveyAnswer(
        questionId: question.id,
        type: 'single_choice',
        choiceIds: [choice.id],
      ),
    ],
  ),
);

Diagnostics, logging, and flushing

Use diagnostics to confirm the SDK is booted, the package version is correct, and queued events are not growing unexpectedly.

Useful diagnostics checks:

  • ready should be true after a successful boot.
  • requiresPermission tells you which app permissions still need user approval.
  • Pending event counts should fall after flush() when the device has connectivity.
  • The reported SDK version should match the package version you installed.
val diagnostics = BubblSdk.diagnostics()
println(diagnostics)
let diagnostics = await BubblClient.shared.diagnostics()
print(diagnostics)
final diagnostics = await BubblSdk.instance.diagnostics();
debugPrint('Bubbl diagnostics: $diagnostics');
const diagnostics = await Bubbl.diagnostics();
console.log('Bubbl diagnostics', diagnostics);

Call flush() after important verification steps or before collecting support evidence:

const result = await Bubbl.flush();
console.log('Pending Bubbl events', result.pendingCount);

The public SDK supports clearing correlation IDs and replacing segments. Do not depend on local-state reset or stored-event replay methods unless they are documented for the exact SDK package installed in your app.

Event streams

Where your platform wrapper exposes SDK events, use them to observe notification, location, geofence, diagnostics, and error events during testing. Events are useful for logging and custom UI, but your app should still handle normal platform permission and notification lifecycle states.

Flutter:

final subscription = BubblSdk.instance.events.listen((event) {
  debugPrint('Bubbl event: $event');
});

React Native:

const subscription = Bubbl.events.addListener(event => {
  console.log('Bubbl event', event);
});

subscription.remove();

Android:

lifecycleScope.launch {
    BubblSdk.events.collect { event ->
        Log.d("Bubbl", "Event: $event")
    }
}

Use event streams for app logging, QA screens, and host-rendered UI. Do not block your core app navigation while waiting for an event; mobile operating systems can deliver notification and location callbacks at different times depending on app state.