val notificationConfig = NotificationConfig(
pushNotificationsEnabled = true, // Enable push notifications
pushDeviceGenerators = listOf(
// Add your desired push device generators here
// You can include multiple generators based on your needs
FirebasePushDeviceGenerator(),
),
)
ChatClient.Builder("api-key", context)
.notifications(notificationConfig, notificationHandler)
.build()
Setup
We support the following providers:
We ship an individual artifact for each of these to make client-side integration with their service quick and simple. See their individual documentation pages linked above for details.
Basic Setup
To enable push notifications, you need to configure the NotificationConfig
with the required PushDeviceGenerator
for your chosen provider. The PushDeviceGenerator
is essential for registering your device with the push notification service.
Required configuration:
pushNotificationsEnabled
: Set totrue
to enable push notifications (enabled by default)pushDeviceGenerators
: List of generators for your chosen push notification provider
boolean pushNotificationEnabled = true;
List<PushDeviceGenerator> pushDeviceGeneratorList = new ArrayList<>();
NotificationConfig notificationConfig = new NotificationConfig(pushNotificationEnabled, pushDeviceGeneratorList);
new ChatClient.Builder("api-key", context)
.notifications(notificationConfig, notificationHandler)
.build();
Push notifications are disabled by default on the client side. You can enable it by setting the NotificationConfig::pushNotificationsEnabled
property to true
.
Keep in mind that the SDK creates a NotificationChannel
during its initialization if push notifications are enabled client-side.
Customizing Push Notifications
If you want, you can also customize how the push notifications work.
You can customize push notifications in the following ways:
- Overriding resources: Lets you customize notification’s icon and text resources
NotificationHandlerFactory
: Uses the styles we provide but customizes an intent the user triggers when clicking on a notification.NotificationHandler
: Lets you fully customize how notifications are shown and dismissedNotificationConfig::shouldShowNotificationOnPush
: Lets you decide whether to show a notification after receiving a push
Overriding resources
You can provide custom icon and text resources displayed in notifications by overriding them:
- We are using stream_ic_notification.xml drawable as the default notification’s icon
- Text resources are placed inside string.xml file
The SDK supports multiple languages. Make sure to override resources in all languages used in your app. Refer to Adding Localization guide for more details.
Using our NotificationHandlerFactory
Our NotificationHandlerFactory
provides a way to create a default implementation of NotificationHandler
based on the Android API Level and lets you customize an intent that a user triggers by clicking the notification.
This function lets you provide a custom Intent
that can point to any Activity
in your app. You can also add custom data to the Intent
if you need it.
val notificationHandler = NotificationHandlerFactory.createNotificationHandler(
context = context,
notificationConfig = notificationConfig,
newMessageIntent = {
message: Message,
channel: Channel,
->
// Return the intent you want to be triggered when the notification is clicked
val intent: Intent = [....]
intent
}
)
ChatClient.Builder("api-key", context)
.notifications(notificationConfig, notificationHandler)
.build()
boolean pushNotificationEnabled = true;
List<PushDeviceGenerator> pushDeviceGeneratorList = new ArrayList<>();
NotificationConfig notificationConfig = new NotificationConfig(pushNotificationEnabled, pushDeviceGeneratorList);
NotificationHandler notificationHandler = NotificationHandlerFactory.createNotificationHandler(context, notificationConfig, (message, channel) -> {
// Return the intent you want to be triggered when the notification is clicked
Intent intent = new Intent();
return intent;
});
new ChatClient.Builder("api-key", context)
.notifications(notificationConfig, notificationHandler)
.build();
Customize Notification Style
The SDK lets you define the theming and behavior of the notification UI that users see after they receive a push notification.
To do this, implement the NotificationHandler
interface and show your own notification.
If you want to dismiss notifications when a user visits a channel or logs off of the app, you will need to implement methods for dismissing notifications on the NotificationHandler
class.
The NotificationHandler
interface provides several methods to handle different types of events:
onChatEvent(event: NewMessageEvent)
: Handles WebSocket events for new messages when the user is connected. This method is only invoked when the user has an active WebSocket connection. You can use this to control whether to show notifications while the user is active in the app. Returntrue
to handle the event yourself,false
to let the SDK handle it internally.onNotificationReminderDueEvent(event: NotificationReminderDueEvent)
: Handles WebSocket events for reminder notifications when the user is connected. This method is only invoked when the user has an active WebSocket connection. Returntrue
to handle the event yourself,false
to let the SDK handle it internally.onPushMessage(message: PushMessage)
: Acts as a bypass to control whether push notifications should be processed when received. Returntrue
to handle the push message yourself,false
to let the SDK handle it internally.showNotification(notification: ChatNotification)
: Shows notifications for different types of notifications (currently new messages and reminder messages, with more types to be added in the future).dismissChannelNotifications(channelType: String, channelId: String)
: Dismisses all notifications for a specific channel.dismissAllNotifications()
: Dismisses all notifications.onNotificationPermissionStatus(status: NotificationPermissionStatus)
: Handles notification permission lifecycle.
class MyNotificationHandler(private val context: Context) : NotificationHandler {
private val notificationManager: NotificationManager by lazy {
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
}
override fun onNotificationPermissionStatus(status: NotificationPermissionStatus) {
when (status) {
NotificationPermissionStatus.REQUESTED -> {
// invoked when POST_NOTIFICATIONS permission is requested
}
NotificationPermissionStatus.GRANTED -> {
// invoked when POST_NOTIFICATIONS permission is granted
}
NotificationPermissionStatus.DENIED -> {
// invoked when POST_NOTIFICATIONS permission is denied
}
NotificationPermissionStatus.RATIONALE_NEEDED -> {
// invoked when POST_NOTIFICATIONS permission requires rationale
}
}
}
override fun showNotification(notification: ChatNotification) {
when (notification) {
is ChatNotification.MessageNew -> {
// Handle new message notification
// You can customize the notification here
}
is ChatNotification.NotificationReminderDue -> {
// Handle reminder notification
// You can customize the notification here
}
}
}
override fun dismissChannelNotifications(channelType: String, channelId: String) {
// Dismiss all notification related with this channel
}
override fun dismissAllNotifications() {
// Dismiss all notifications
}
}
class MyNotificationHandler implements NotificationHandler {
NotificationManager notificationManager;
public MyNotificationHandler(Context context) {
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE) ;
}
@Override
public void onNotificationPermissionStatus(@NonNull NotificationPermissionStatus status) {
switch (status) {
case REQUESTED:
// invoked when POST_NOTIFICATIONS permission is requested
break;
case GRANTED:
// invoked when POST_NOTIFICATIONS permission is granted
break;
case DENIED:
// invoked when POST_NOTIFICATIONS permission is denied
break;
case RATIONALE_NEEDED:
// invoked when POST_NOTIFICATIONS permission requires rationale
break;
}
}
@Override
public void showNotification(@NonNull ChatNotification notification) {
if (notification instanceof ChatNotification.MessageNew) {
ChatNotification.MessageNew messageNew = (ChatNotification.MessageNew) notification;
// Handle new message notification
// You can customize the notification here
} else if (notification instanceof ChatNotification.NotificationReminderDue) {
ChatNotification.NotificationReminderDue reminderDue = (ChatNotification.NotificationReminderDue) notification;
// Handle reminder notification
// You can customize the notification here
}
}
@Override
public void dismissChannelNotifications(@NonNull String channelType, @NonNull String channelId) {
// Dismiss all notification related with this channel
}
@Override
public void dismissAllNotifications() {
// Dismiss all notifications
}
}
Finally, pass as the NotificationHandler
implementation to the ChatClient.Builder
when initializing the Stream Android SDK:
val notificationHandler = MyNotificationHandler(context)
ChatClient.Builder("api-key", context)
.notifications(notificationConfig, notificationHandler)
.build()
NotificationHandler notificationHandler = new MyNotificationHandler(context);
new ChatClient.Builder("api-key", context)
.notifications(notificationConfig, notificationHandler)
.build();
Advanced Notification Configuration
The NotificationConfig
class provides comprehensive control over push notification behavior. Here’s a detailed explanation of each property:
WebSocket Connection Behavior
ignorePushMessageWhenUserOnline: (type: String) -> Boolean
Controls whether push notifications should be shown when the user has an active WebSocket connection. This allows you to customize behavior based on notification type.
Supported notification types:
ChatNotification.TYPE_MESSAGE_NEW
- New message notificationsChatNotification.TYPE_NOTIFICATION_REMINDER_DUE
- Reminder notifications
Default behavior:
- New message notifications are ignored when the user has an active WebSocket connection
- Reminder notifications are always shown, even when the user has an active WebSocket connection
val notificationConfig = NotificationConfig(
ignorePushMessageWhenUserOnline = { type ->
when (type) {
ChatNotification.TYPE_MESSAGE_NEW -> true // Ignore new messages when online
ChatNotification.TYPE_NOTIFICATION_REMINDER_DUE -> false // Always show reminders
else -> true // Default behavior for unknown types
}
}
)
Runtime Notification Control
shouldShowNotificationOnPush: () -> Boolean = { true }
Allows you to control whether notifications should be displayed after receiving a push message. This function is called for each push notification received and can be changed at runtime.
This is particularly useful when users want to temporarily disable notifications or when you need to implement custom logic based on your app’s internal state.
val notificationConfig = NotificationConfig(
shouldShowNotificationOnPush = {
// Custom logic to determine if notification should be shown
// For example, only show notifications during certain hours
val currentHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY)
currentHour in 8..22 // Only show notifications between 8 AM and 10 PM
}
)
Permission Management
requestPermissionOnAppLaunch: () -> Boolean = { true }
Controls whether the SDK should automatically request the POST_NOTIFICATIONS
permission when the app launches. This is particularly important for Android 13+ where notification permission is required.
val notificationConfig = NotificationConfig(
requestPermissionOnAppLaunch = {
// Custom logic to determine if permission should be requested
// For example, only request on first app launch
isFirstAppLaunch()
}
)
Advanced Features
autoTranslationEnabled: Boolean = false
Enables or disables the auto-translation feature for push notifications. When enabled, notifications will be automatically translated based on the user’s language preferences.
val notificationConfig = NotificationConfig(
autoTranslationEnabled = true // Enable automatic translation
)
tokenProvider: TokenProvider? = null
A token provider used when restoring user credentials and an expired token needs to be refreshed. This is particularly useful when using expiring tokens, as push notifications can arrive at any time, even after the app has been closed.
val notificationConfig = NotificationConfig(
tokenProvider = CustomTokenProvider() // Your custom token provider
)
Complete Configuration Example
Here’s a complete example showing how to configure all properties:
val notificationConfig = NotificationConfig(
// WebSocket connection behavior
ignorePushMessageWhenUserOnline = { type ->
when (type) {
ChatNotification.TYPE_MESSAGE_NEW -> true
ChatNotification.TYPE_NOTIFICATION_REMINDER_DUE -> false
else -> true
}
},
// Runtime notification control
shouldShowNotificationOnPush = {
val currentHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY)
currentHour in 8..22
},
// Permission management
requestPermissionOnAppLaunch = { true },
// Advanced features
autoTranslationEnabled = true,
tokenProvider = null // Use default token provider
)
ChatClient.Builder("api-key", context)
.notifications(notificationConfig, notificationHandler)
.build()
NotificationConfig notificationConfig = new NotificationConfig(
type -> { // ignorePushMessageWhenUserOnline
switch (type) {
case ChatNotification.TYPE_MESSAGE_NEW:
return true;
case ChatNotification.TYPE_NOTIFICATION_REMINDER_DUE:
return false;
default:
return true;
}
},
() -> { // shouldShowNotificationOnPush
Calendar calendar = Calendar.getInstance();
int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
return currentHour >= 8 && currentHour <= 22;
},
() -> true, // requestPermissionOnAppLaunch
false, // autoTranslationEnabled
null // tokenProvider
);
new ChatClient.Builder("api-key", context)
.notifications(notificationConfig, notificationHandler)
.build();
Dismissing notifications
Our MessageListView
UI component and MessageList
Compose UI Component automatically dismiss notifications related to a Channel
when the user opens it.
If you need to dismiss them manually (for example, if you are using a custom MessageListView
component) you can call the ChatClient::dismissChannelNotifications
method, providing the channelType
and channelId
from the Channel
that you would like to dismiss notifications:
ChatClient.instance().dismissChannelNotifications("messaging", "general")
ChatClient.instance().dismissChannelNotifications("messaging", "general");
Notifications are also automatically dismissed when the user logs out from the SDK.