ChangelogEdit pageSTAFFOpen dashboard

Permissions and privacy

Ask for notifications and location through Bubbl, with the dashboard's privacy view first if you want one, or keep your own permission flow.

Bubbl uses two permissions: notifications, to show its notifications when your app isn't in front, and location, for geofences. It never prompts on its own. Your app decides when to ask, through Bubbl.permissions or through its own flow.

Asking through Bubbl#

KOTLIN
// From a coroutine (suspend functions)
val notifications = Bubbl.permissions.requestNotifications()   // Android 13+; before that there's nothing to ask
val location = Bubbl.permissions.requestLocation(always = true)

// Or with a callback, from Kotlin or Java
Bubbl.permissions.requestLocation(true) { status -> /* BubblPermissionStatus? */ }
JAVA
Bubbl.Permissions.requestLocation(true, status -> { /* BubblPermissionStatus, or null */ });
SWIFT
let notifications = await Bubbl.permissions.requestNotifications()
let location = await Bubbl.permissions.requestLocation(always: true)

// Or with a completion handler, called on the main thread
Bubbl.permissions.requestLocation(always: true) { status in /* BubblPermissionStatus? */ }
DART
final notifications = await Bubbl.permissions.requestNotifications();
final location = await Bubbl.permissions.requestLocation(always: true);
TS
const notifications = await Bubbl.permissions.requestNotifications();
const location = await Bubbl.permissions.requestLocation({ always: true });

Each request works from anywhere in your app, with no activity or view controller of yours needed. It shows Bubbl's privacy view first if the dashboard says so, then the system prompt, and returns where the device stands afterwards. With always set to true, requestLocation also asks for the second step: "Allow all the time" on Android 11 and later, and from "While Using" to "Always" on iOS. Without it, it asks for location while the app is in use only.

If the user taps "Not now" in the privacy view, or refuses the system prompt, the request ends there. Requests return null before start, and where Bubbl isn't supported.

Where the device stands#

Bubbl.permissions.status() returns a BubblPermissionStatus, or null before start:

  • notifications: granted, denied or not determined;
  • location: always, when in use, denied or not determined;
  • preciseLocation: true for precise rather than approximate location.

The case names follow each language: GRANTED, WHEN_IN_USE and NOT_DETERMINED in Kotlin; .granted, .whenInUse and .notDetermined in Swift and Dart; 'granted', 'whenInUse' and 'notDetermined' in TypeScript. It's synchronous on Android and iOS, and a Future or Promise in Flutter and React Native. On iOS it's where the device stood when Bubbl last looked (at start, on every return to the app and after each request), so it can be null just after start, until that first look.

Sending the user to Settings#

iOS shows each system prompt only once, and Android stops showing it after repeated refusals. After that, only Settings can change the answer. Bubbl.permissions.openSettings() opens your app's page in system Settings. It works before start too, so you can use it for your app's own permissions, like the camera.

The privacy view#

The privacy view is Bubbl's own screen explaining why the app wants a permission, shown before the system prompt. You set it up in the dashboard under Configuration › Plugin:

SettingWhereWhat it does
Privacy viewRuntimeShow automatically: the first time each kind of permission is asked for. Always show: before every prompt. Never show: straight to the prompt.
Privacy textCallbacks & privacyYour own words for the view. Without them, Bubbl uses its built-in text.
Privacy policy linkCallbacks & privacyThe privacy policy the view links to.

Changes reach devices when the SDK next refreshes its settings. See Privacy for the dashboard side.

The built-in titles and texts are string resources you can reword or translate, such as bubbl_permission_location_title, bubbl_permission_background_body, bubbl_continue and bubbl_not_now. See Appearance and text.

Your own permission flow#

You don't have to use Bubbl.permissions. Bubbl uses whatever the user allowed, however it was asked: your own prompt, a library such as permission_handler, or Settings. On iOS, Bubbl picks up notification permission given elsewhere at the next app open and asks for the device token then.

Google Play's prominent disclosure#

Google Play requires a prominent disclosure before asking for background location. requestLocation(always = true) shows Bubbl's privacy view as that disclosure when the privacy view is set to Show automatically or Always show. If it's set to Never show, or you ask for background location yourself, show your own disclosure first. See Location and geofences for the Play Console declaration.

iOS usage strings and privacy manifest#

iOS won't show a location prompt without NSLocationWhenInUseUsageDescription and NSLocationAlwaysAndWhenInUseUsageDescription in your Info.plist. The SDK ships Apple's privacy manifest (PrivacyInfo.xcprivacy), which Xcode folds into your app's privacy report.