Skip to content
Back to archipelago.banuacoder.com

Feature SDKs (Pro)

push_notification_onesignal Pro ​

Tier
Proversion 1.3.5
Command
archipelago generate push_notification_onesignal
Generates
  • features/push_notification/push_notification_onesignal_impl
Generates first
push_notification_sdkwhen needed and missing, so there is nothing to install first
Depends on
shared_consentgenerate these first

OneSignal provider implementation for push_notification_sdk. Generates push_notification_onesignal_impl — a PushNotificationProviderHandler backed by the OneSignal Flutter SDK v5.x — and wires it into the same DI chain as the free FCM provider. Needs push_notification_sdk and generates it first when it is missing; it adds a provider, it does not replace the SDK.

Variables ​

VariableTypeDefaultDescription
oneSignalAppIdstring''Your OneSignal App ID (Settings > Keys & IDs in the OneSignal dashboard). Not a secret — baked directly into the generated handler's OneSignal.initialize() call. If left empty, post_gen prints a warning naming the file to fix.
isForMonorepobooleantrueWhether this is being generated as part of a monorepo.

Install ​

Interactive ​

bash
archipelago generate push_notification_onesignal

Non-interactive (CI) ​

bash
archipelago generate push_notification_onesignal --config my_config.json

When archipelago.yaml does not list push_notification_sdk, pre_gen generates it first with its defaults. push_notification_sdk requires FCM (includeFcm: true), so OneSignal always runs next to FCM. Before 1.3.1 the brick stopped with "push_notification_onesignal requires push_notification_sdk to be installed first" instead.

Relationship to push_notification_sdk ​

push_notification_sdk is the free FCM-based push feature (contract PushNotificationSDK/PushNotificationProviderHandler, orchestrator PushNotificationSDKImpl, and — if includeFcm is true — push_notification_fcm_impl). push_notification_onesignal is an additive vendor provider, exactly like analytics_sdk's vendor bricks: it adds PushNotificationProvider.oneSignal (already present in the shared PushNotificationProvider enum) alongside FCM, not instead of it. Both providers can be installed together; the orchestrator discovers all registered PushNotificationProviderHandlers via getIt.getAll().

Generated Package ​

PackagePurpose
push_notification_onesignal_implPushNotificationProviderHandler implementation backed by onesignal_flutter

Generated Structure ​

text
features/
└── push_notification/
    └── push_notification_onesignal_impl/
        └── lib/src/
            ├── onesignal_push_notification_handler.dart
            └── di/

Public API ​

You don't call this package directly — go through the shared PushNotificationSDK from push_notification_sdk, which fans out to every registered provider:

dart
final push = getIt<PushNotificationSDK>();
await push.requestPermission();
final token = await push.getToken(); // returns whichever provider(s) are registered

OneSignalPushNotificationHandler itself implements the same PushNotificationProviderHandler contract FCM does: requestPermission(), getPermissionStatus(), getToken(), subscribeToTopic()/unsubscribeFromTopic(), foregroundStream, tapStream, clearAll().

Notification policy (since 1.3.0) ​

Every foreground message passes the notification policy from push_notification_sdk (1.3.1 or later) before OneSignal displays it. See the decision flow.

  1. The will-display listener calls event.preventDefault() at once, which holds the OneSignal banner while the policy runs.
  2. Suppressed messages (no marketing consent, quiet hours, cap reached) are never shown and never emitted.
  3. Shown messages are emitted on foregroundStream. Only messages without publicTitle get display(): untagged and tier: marketing messages.

Untagged messages are unchanged. A message without a tier (in OneSignal's "Additional Data") keeps the OneSignal banner and its real title and body, exactly as before the policy. Redaction is opt-in: messages the sender marks sensitive (explicit tier: critical / tier: transactional, or sensitive: "true") get no OneSignal banner in the foreground, because the device cannot give that banner lock-screen-safe text. The app displays them from foregroundStream with publicTitle / publicBody as the lock-screen version. Background deliveries are not affected.

A sensitive message with detail_title or detail_body in its Additional Data (the detail split) also gets no OneSignal banner: the app shows the detail text, and the OneSignal heading and content become publicTitle / publicBody. A non-sensitive message with these keys keeps its banner and its heading and content, as before the split. To send this split from your server, see Notification policy on your backend.

Topics are simulated via tags ​

OneSignal has no first-class "topic" concept. subscribeToTopic(topic) sets a tag topic_<name> = "true"; unsubscribeFromTopic(topic) removes that tag. Build server-side segments on these tags if you rely on OneSignal-side targeting.

DI & Wiring ​

  • PushNotificationOnesignalImplPackageModule registers OneSignalPushNotificationHandler as @Named('oneSignal') @LazySingleton(as: PushNotificationProviderHandler), so it coexists with the FCM handler.
  • Ordering matters: PushNotificationGlobalModule.init() (the orchestrator) eagerly calls getAll<PushNotificationProviderHandler>(), so every handler must already be registered when it runs. post_gen first patches push_notification_impl/pubspec.yaml's archipelago: di_modules: depends_on: list to add push_notification_onesignal_impl, then registers the OneSignal module in injector.dart; the manifest-driven resolver uses that depends_on graph to order the injector so every handler is registered before the orchestrator, and regeneration with monorepo_toolkit generate host-registry keeps that order.
  • OneSignalPushNotificationHandler has no @module/register_module.dart provider methods — OneSignal's Flutter SDK is a static API surface (OneSignal.*), so there's no instance to provide via DI. The file exists only to mirror the FCM package's structure.
  • Consent-gated: the handler calls OneSignal.consentRequired(true) before initialize() and follows ConsentPurpose.marketing from ConsentGateRegistry, so OneSignal stays dormant until the user consents. Init failures are caught and logged, never rethrown.

Dependencies ​

onesignal_flutter ^5.6.7, consent_api, and push_notification_api from push_notification_sdk 1.3.1 or later (for NotificationPolicyRegistry and opt-in redaction).

Platform Setup ​

Not automated by this brick's hooks — no AndroidManifest.xml, Info.plist, or Gradle file is touched by post_gen.dart. You must still, per OneSignal's own Flutter SDK setup:

  • Create a OneSignal app in the OneSignal dashboard and obtain its App ID.
  • Supply the App ID at generation time via oneSignalAppId; the handler calls OneSignal.initialize(appId) itself from its constructor, and every handler method waits for it before touching OneSignal. If you left it empty, replace the empty App ID in onesignal_push_notification_handler.dart.
  • Follow OneSignal's platform setup (Firebase Server Key for Android, APNs key for iOS) per https://documentation.onesignal.com/docs/flutter-sdk-setup.

Limitations ​

  • clearAll() opts the device out of push (pushSubscription.optOut()) but deliberately does not close its internal stream controllers or unregister its OneSignal listeners — this handler is a process-lifetime LazySingleton, so closing them would permanently break foregroundStream/tapStream after the first logout. A brief window between optOut() and re-login can still deliver events; apps with strict requirements should unregister/re-register listeners around the auth cycle themselves.
  • Requires push_notification_sdk pre-installed (guard-and-fail, not self-generated — see Install above).

Changelog ​

Run archipelago brick info push_notification_onesignal to see the latest published version. Enterprise customers can read the full CHANGELOG.md in the brick source repository.