Push notifications
Enable push notifications in your app using the Flutter SDK
Engagement enables sending push notifications to your app users using scenarios. The mobile application handles the push message using the SDK and renders the notification on the customer's device.
Push notifications can also be silent, used only to update the app’s interface or trigger some background task.
Refer to Mobile push notifications to learn how to create push notifications in the Engagement web app.
Also see Mobile push notifications FAQ at Bloomreach Support Help Center.
Integration
The Flutter SDK relies on the underlying native Android and iOS platforms to handle push notifications. Use the checklist below to complete all required setup steps for both platforms.
Push notifications integration checklist
Complete these steps in order to ensure reliable push notification delivery and accurate event tracking.
-
Set up native platform dependencies
- Ensure your Flutter project is configured for both Android and iOS native integrations.
-
Android integration
- Set up a Firebase project and add the
google-services.jsonfile to your Android project. Refer to the Firebase Cloud Messaging guide for step-by-step instructions. - Implement Firebase messaging by registering a
FirebaseMessagingServicesubclass in your app. - Configure the Firebase Cloud Messaging integration in the Engagement web app.
- Grant notification permission at runtime (required for Android 13+, API level 33+).
- Follow all steps described in the Android push notifications guide.
- Set up a Firebase project and add the
-
iOS integration
- Obtain an Apple Push Notification service (APNs) authentication token signing key.
- Add and configure the APNs integration in the Engagement web app.
- Enable push capabilities, background modes, and app groups in your app using Xcode.
- Extend your app's
AppDelegatewithExponeaFlutterAppDelegateto handle push notification events. - Request notification permission on application startup.
- Complete the setup steps in the iOS push notifications guide.
-
SDK self-check (optional but recommended)
- Before initializing the SDK, call
ExponeaPlugin().checkPushSetup()on each platform to verify a successful push setup.
- Before initializing the SDK, call
-
Test your implementation
- Send test push notifications from the Engagement web app and confirm delivery, receipt, and interaction tracking in your app.
- Register listeners (
openedPushStream,receivedPushStream) to handle notification interactions and delivery events.
-
Refer to platform-specific documentation
- For advanced configuration, troubleshooting, or additional features, consult:
- Android (Firebase) setup guide
- iOS setup guide
- Flutter SDK push notifications documentation for customization, deep linking, and event tracking.
- For advanced configuration, troubleshooting, or additional features, consult:
Platform-specific integration guides
The following pages describe the steps for each platform to add the minimum push notification functionality (receive alert notifications) to your app:
Customization
This section describes the customizations you can implement once you have integrated the minimum push notification functionality.
Configure automatic push notification tracking
By default, the SDK tracks push notifications automatically. The SDK will display push notifications from Engagement and track a "campaign" event for every delivered/opened push notification with the relevant properties.
In the SDK configuration, you can set the desired frequency with which the SDK tracks the push notification token to Engagement using the pushTokenTrackingFrequency property (default value is TokenFrequency.onTokenChange).
On Android, you can disable automatic push notification tracking by setting the Boolean value of the automaticPushNotifications property to false in the SDK's Android-specific configuration.
❗️Important
- The Flutter SDK currently doesn't support disabling automatic push notification tracking on iOS.
- SDK versions 2.3.0 and higher use event-based token tracking to support multiple mobile applications per project. Learn more about Token tracking via notification_state event.
Respond to push notification interactions
Once you have followed the integration steps for each platform, your app should be able to receive push notifications.
To respond to a push notification interaction, you can set up a listener to ExponeaPlugin().openedPushStream:
import 'package:exponea/exponea.dart';
final _plugin = ExponeaPlugin();
final subscription = _plugin.openedPushStream.listen((openedPush) {
switch(openedPush.action) {
case PushActionType.app:
// last push directed user to your app with no link
// log data defined on Exponea backend
print('app - ${openedPush.data}');
break;
case PushActionType.deeplink:
// last push directed user to your app with deeplink
print('deeplink - ${openedPush.url}');
break;
case PushActionType.web:
// last push directed user to web, nothing to do here
print('web');
break;
}
});
Call subscription.cancel() when you no longer need the listener.
We recommend registering the listener as soon as possible to ensure proper application flow. However, the SDK will hold the last push notification and call the listener once it's registered.
To support deep links, additional set up steps are required. Refer to the documentation for the respective native platforms (Android, iOS). Alternatively, use the
Open appaction instead and add your payload toAdditional data.
Respond to received push notifications
You can set up a listener for received push notifications using ExponeaPlugin.receivedPushStream, which is especially useful for silent push notifications.
final subscription = _plugin.receivedPushStream.listen((receivedPush) {
print(receivedPush);
});
Call subscription.cancel() when you no longer need the listener.
We recommend registering the listener as soon as possible to ensure proper application flow. However, the SDK will hold the last push notification and call the listener once it's registered.
The listener is called for both regular and silent push notifications on Android but only for silent push notifications on iOS due to technical limitations.
Manually track push notifications
If you disable automatic push notification tracking (Android only) or if you want to track push notification from other providers, you can manually track events related to push notifications.
The Flutter SDK currently doesn't support disabling automatic push notification tracking on iOS.
Track push token (FCM)
Use the trackPushToken method to manually track the FCM push token:
ExponeaPlugin().trackPushToken("382d4221-3441-44b7-a676-3eb5f515157f")
Invoking this method will track the push token immediately regardless of the SDK configuration for pushTokenTrackingFrequency.
❗️Important
SDK versions 2.3.0 and higher use event-based token tracking to support multiple mobile applications per project. Learn more about Token tracking via notification_state event.
Track delivered push notification
Use the trackDeliveredPush method to manually track a delivered push notification:
final Map<String, dynamic> payload = {
"platform": "android",
"subject": "subject",
"type": "push",
"url_params": {
"utm_campaign": "Campaign name",
"utm_medium": "mobile_push_notification",
"utm_content": "en",
...
},
...
};
ExponeaPlugin().trackDeliveredPush(payload)
The behaviour of
trackDeliveredPushmay be affected by the tracking consent feature, which, when enabled, requires explicit consent for tracking. Read more in the tracking consent documentation.
Track clicked push notification
Use the trackClickedPush method to manually track a clicked push notification:
final Map<String, dynamic> payload = {
"platform": "android",
"subject": "subject",
"type": "push",
"url_params": {
"utm_campaign": "Campaign name",
"utm_medium": "mobile_push_notification",
"utm_content": "en",
...
},
...
};
ExponeaPlugin().trackClickedPush(payload)
The behaviour of
trackClickedPushmay be affected by the tracking consent feature, which, when enabled, requires explicit consent for tracking. Read more in the tracking consent documentation.
Custom push notification data processing
If the provided native ExponeaModule.Companion.handleRemoteMessage (Android) and ExponeaNotificationService().process (iOS) methods don't fit the requirements of your app, or you decide to disable automatic push notifications, you must handle push notifications and process their payload yourself.
Notification payloads are generated from (possibly complex) scenarios in the Engagement platform and contain all data for Android, iOS and web platforms. Therefore, the payload itself can be complex.
Notification payloads use a JSON data structure.
Payload example
{
"notification_id": 123,
"url": "https://example.com/main_action",
"title": "Notification title",
"action": "app|browser|deeplink|self-check",
"message": "Notification message",
"image": "https://example.com/image.jpg",
"actions": [
{"title": "Action 1", "action": "app|browser|deeplink", "url": "https://example.com/action1"}
],
"sound": "default",
"aps": {
"alert": {"title": "Notification title", "body": "Notification message"},
"mutable-content": 1
},
"attributes": {
"event_type": "campaign",
"campaign_id": "123456",
"campaign_name": "Campaign name",
"action_id": 1,
"action_type": "mobile notification",
"action_name": "Action 1",
"campaign_policy": "policy",
"consent_category": "General consent",
"subject": "Subject",
"language": "en",
"platform": "ios|android",
"sent_timestamp": 1631234567.89,
"recipient": "[email protected]"
},
"url_params": {"param1": "value1", "param2": "value2"},
"source": "xnpe_platform",
"silent": false,
"has_tracking_consent": true,
"consent_category_tracking": "Tracking consent name"
}
Token tracking via notification_state event
Starting with SDK version 2.3.0, push notification tokens are tracked using notification_state events instead of customer
profile properties. This change enables support for multiple mobile applications per project,
allowing you to track multiple push tokens for the same customer across different apps and devices.
Token storage by SDK version
SDK versions below 2.3.0:
- Tokens are stored in customer profile properties:
google_push_notification_id,huawei_push_notification_id, orapple_push_notification_id - One token per customer profile
- Single application per project
SDK versions 2.3.0 and higher:
- Tokens are stored as
notification_stateevents - Multiple tokens per customer (grouped by Application ID)
- Multiple applications per project supported
- Backward compatibility maintained for Application ID
default-application
When notification_state events are tracked
The SDK automatically tracks notification_state events in the following scenarios:
- SDK initialization
- App transitions from background to foreground
- New token received from Firebase, Huawei, or APNs
- Manual token tracking using
ExponeaPlugin().trackPushToken(...)(Android, iOS) orExponeaPlugin().trackHmsPushToken(...)(Huawei) - User anonymization via
ExponeaPlugin().anonymize() - Notification permission requested via
ExponeaPlugin().requestPushAuthorization()
_plugin.requestPushAuthorization()
.then((accepted) => print("User has ${accepted ? 'accepted': 'rejected'} push notifications."))
.catchError((error) => print('Error: $error'));
The frequency of notification_state event tracking depends on the pushTokenTrackingFrequency configuration property. See SDK configuration.
notification_state event properties
| Property | Description | Example values |
|---|---|---|
push_notification_token | Current push notification token | Token string |
platform | Mobile platform | android, huawei, or iOS |
valid | Token validity status | true or false |
description | Token state description | Permission granted, Permission denied, or Invalidated |
application_id | Application identifier from SDK configuration | Custom ID or default-application (default) |
device_id | Unique device identifier | UUID string |
Note
If you don't specify an
application_idin your SDK configuration, the default valuedefault-applicationis used. See SDK configuration.
Understanding token states
The combination of valid and description properties indicates the token's current state:
| Valid | Description | When this occurs |
|---|---|---|
false | Invalidated | New token received (old token becomes invalid) or ExponeaPlugin().anonymize() called |
false | Permission denied | requirePushAuthorization is true and user denied notification permission |
true | Permission granted | Valid token tracked successfully (all other cases) |
Configuring Application ID
Note
See this section to configure
application_id. Configure Application ID.
❗️Important
The SDK can automatically generate
notification_stateevents,
but your Engagement project must have event creation enabled. If your project uses custom event schemas
or restricts event creation, addnotification_stateto the list of allowed events. Otherwise, push token registration will fail silently.
Verifying token tracking
You can verify that tokens are being tracked correctly in the Bloomreach Engagement web application:
- Navigate to Data & Assets > Customers
- Locate the customer profile
- Check for
notification_stateevents in the customer's event history - Verify the
push_notification_tokenproperty contains a valid token value
For SDK versions below 2.3.0, check the customer profile properties google_push_notification_id, huawei_push_notification_id, or apple_push_notification_id.
Updated 19 days ago
