Last Edit: Mar 03 2020

The most common use case for client level events are unread counts. Here's an example of a complete unread count integration for your chat app. As a first step we get the unread count when the user connects:

const user = await client.setUser({ id: 'myid' }, token);

// response.me.total_unread_count returns the unread count
// response.me.unread_channels returns the count of channels with unread messages

final response = await client.setUser(user, "{{ chat_user_token }}");

print("There are ${response.me.unreadChannels} unread channels");
print("There are ${response.me.totalUnreadCount} unread messages");

client.setUser(User(userId), "{{ chat_user_token }}", object : InitConnectionListener() {
    override fun onSuccess(data: ConnectionData) {
        val user = data.user
        val unreadChannels = user.unreadChannels
        val totalUnreadCount = user.totalUnreadCount

By default the UI component SDKs (React, React Native, ...) mark messages as read automatically when the channel is visible. You can also make the call manually like this:

// mark all messages on a channel as read
await channel.markRead();

await channel.markRead();

channelController.markRead().enqueue {
    val readEvent = it.data()

While you're using the app, the unread count can change. A user can be added to a channel, a new message can be created, or the user can mark the messages as seen on another tab/device.

Unread counts are only stored and returned at connection time for channel members.

The markRead function can also be executed server-side by passing a user ID as shown in the example below:

// mark all messages on a channel as read (server side)
await channel.markRead({ user_id: 'foo' });

// mark all messages on a channel as read (server side)
$mark = $channel->markRead('user-id');

// This example is only for server-side clients

To support updating the unread count in realtime, you can listen to these events.

  1. notification.added_to_channel

  2. notification.removed_from_channel

  3. notification.message_new

  4. notification.mark_read

All 4 of these events include the fields: total_unread_count and unread_channels. You can listen to them all at once like this:

client.on((event) => {
     if (event.total_unread_count !== undefined) {

     if (event.unread_channels !== undefined) {

client.on().where((Event event) => event.unreadChannels != null).listen((Event event) {
  print("Unread channels count changed to:${event.unreadChannels}");

client.on().where((Event event) => event.totalUnreadCount != null).listen((Event event) {
  print("Unread messages count changed to:${event.totalUnreadCount}");

    .filter { event ->
        event.unreadChannels != null && event.totalUnreadCount != null
    }.subscribe { event ->
        val unreadChannels = event.unreadChannels
        val totalUnreadCount = event.totalUnreadCount