Android Push Notifications
Enable push notifications on Android using the Flutter SDK
The Flutter SDK relies on the native Android SDK to handle push notifications on Android. This guide provides shortened instructions for Android within the context of the Flutter SDK and refers to the push notifications documentation for the Android SDK for details.
The SDK provides a push setup self-check feature to help developers successfully set up push notifications. The self-check will try to track the push token, request the Engagement backend to send a silent push to the device, and check if the app is ready to open push notifications.
To enable the setup check, call
ExponeaPlugin().checkPushSetup()
before initializing the SDK:
The behaviour of push notification delivery and click tracking may be affected by the tracking consent feature, which, if enabled, requires explicit consent for tracking. Refer to the tracking consent documentation for details.
Integration
Exponea Android SDK supports the following integrations:
Standard (Firebase) Integration
To be able to send push notifications from the Engagement platform and receive them in your app on Android devices, you must:
- Set up a Firebase project.
- Implement Firebase messaging in your app.
- Configure the Firebase Cloud Messaging integration in the Engagement web app.
Follow the instructions in Firebase Cloud Messaging in the native Android SDK documentation.
Note that the root of your Android project is
/android
.
Please note that with Google deprecating and removing the FCM legacy API in June 2024, Bloomreach Engagement is now using Firebase HTTP v1 API.
Huawei Integration
To be able to send push notifications from the Engagement platform and receive them in your app on Huawei devices, you must:
- Set up Huawei Mobile Services (HMS)
- Implement HMS in your app.
- Configure the Huawei Push Service integration in the Engagement web app.
Follow the instructions in Huawei Mobile Services in the native Android SDK documentation.
Request Notification Permission
As of Android 13 (API level 33), a new runtime notification permission POST_NOTIFICATIONS
must be registered in your AndroidManifest.xml
and must also be granted by the user for your application to be able to show push notifications.
The SDK already registers the POST_NOTIFICATIONS
permission.
The runtime permission dialog to ask the user to grant the permission must be triggered from your application. You may use SDK API for that purpose:
_plugin.requestPushAuthorization()
.then((accepted) => print("User has ${accepted ? 'accepted': 'rejected'} push notifications."))
.catchError((error) => print('Error: $error'));
The behavior of this callback is as follows:
- For Android API level <33:
- Permission is not required, return
true
automatically.
- Permission is not required, return
- For Android API level 33+:
- Show the dialog, return the user's decision (
true
/false
). - In case of previously granted permission, don't show the dialog return
true
.
- Show the dialog, return the user's decision (
Customization
Enable Deep Linking
You can use ExponeaPlugin().openedPushStream
to define a [listener that will respond to push notification interactions(flutter-sdk-push-notifications#respond-to-push-notification-interactions). To enable deep linking, you must make some changes to AndroidManifest
in android/src/main
.
Set activity to single task launch mode
By default, Android will launch a new activity for your application when the user opens a deep link. You must override this behavior by setting android:launchMode="singleTask"
for your main activity:
<activity
android:name=".MainActivity"
...
android:launchMode="singleTask"
>
Define an intent filter
You must also define an intent filter that can respond to push notification's link. You can either use a custom scheme or a URL. Refer to the relevant official Android documentation for more information.
<activity ...>
...
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with "exponea://action”-->
<data android:scheme="exponea" android:host="action" />
<!-- Accepts URIs that begin https://www.example.com -->
<data android:scheme="https" android:host="www.example.com" />
</intent-filter>
</activity>
Show Foreground Notifications
By default, if a notification arrives while the app is in the foreground, the notification ends up in the notification drawer and a notification icon appears in the status bar.
To enable notification banners while the app is in the foreground, you can set up a listener for received push notifications using ExponeaPlugin.receivedPushStream
and implement display of the notification banner using a third-party plugin such as flutter_local_notifications.
final subscription = _plugin.receivedPushStream.listen((receivedPush) {
_showPushNotification(receivedPush);
});
Call subscription.cancel()
when you no longer need the listener.
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.
Troubleshooting
If push notifications aren't working as expected in your app, consider the following frequent issues and their possible solutions:
Clicking on a push notification does not open the app on Xiaomi Redmi devices
Xiaomi MIUI handles battery optimization in its own way, which can sometimes affect the behavior of push notifications.
If battery optimization is on for devices running MIUI, it can make push notifications stop showing or not working after the click. Unfortunately, there is nothing we can do on our end to prevent this, but you can try this to solve the issues:
- Turn off any battery optimizations in
Settings
>Battery & Performance
. - Set the "No restrictions" option in the battery saver options for your app.
- And (probably) most important, turn off
Memory and MIUI Optimization
underDeveloper Options
.
Push notification token is missing after anonymization
Your app may be using ExponeaPlugin().anonymize()
as a sign out feature.
Keep in mind that invoking the anonymize
method will remove the push notification token from storage. Your application should retrieve a valid token manually before using any push notification features. You may do this directly after anonymize
or before or after identifyCustomer
, depending on your push notifications usage.
import android.os.Bundle
import com.exponea.ExponeaPlugin
import io.flutter.embedding.android.FlutterActivity
class MainActivity : FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
FirebaseMessaging.getInstance().token.addOnSuccessListener {
ExponeaPlugin.handleNewGmsToken(applicationContext, it)
}
}
}
Updated 8 days ago