Listening for Events

LAST EDIT Apr 12 2021

As soon as you call watch on a Channel or queryChannels you’ll start to listen to these events. You can hook into specific events:

1
2
3
4
channel.on('message.deleted', event => { 
    console.log('event', event); 
    console.log('channel.state', channel.state); 
});
1
2
3
4
5
6
7
8
9
10
11
12
ChannelClient channelClient = client.channel("messaging", "general"); 
 
// Subscribe for new message events 
Disposable disposable = channelClient.subscribeFor( 
        new Class[]{NewMessageEvent.class}, 
        (ChatEvent event) -> { 
            Message message = ((NewMessageEvent) event).getMessage(); 
        } 
); 
 
// Dispose when you want to stop receiving events 
disposable.dispose();
1
2
3
4
5
6
7
8
let channel = Client.shared.channel(type: .messaging, id: "general") 
 
let subscription = channel.subscribe(forEvents: [.messageNew]) { event in 
	// handle new message event 
} 
 
// Cancel subscription when you want to stop receiving events 
subscription.cancel()
1
2
3
4
5
6
7
8
9
val channelClient = client.channel("messaging", "general") 
 
// Subscribe for new message events 
val disposable: Disposable = channelClient.subscribeFor<NewMessageEvent> { newMessageEvent -> 
    val message = newMessageEvent.message 
} 
 
// Dispose when you want to stop receiving events 
disposable.dispose()
1
2
3
channel.on("message.deleted").listen((Event event) { 
  print("message ${event.message.id} was deleted"); 
});

You can also listen to all events at once:

1
2
3
4
channel.on(event => { 
    console.log('event', event); 
    console.log('channel.state', channel.state); 
});
1
2
3
4
5
6
7
8
9
Disposable disposable = client.subscribe((ChatEvent event) -> { 
    // Check for specific event types 
    if (event instanceof NewMessageEvent) { 
        Message message = ((NewMessageEvent) event).getMessage(); 
    } 
}); 
 
// Dispose when you want to stop receiving events 
disposable.dispose();
1
2
3
4
5
6
7
8
let channel = Client.shared.channel(type: .messaging, id: "general") 
 
let subscription = channel.subscribe { event in 
	// handle new event 
} 
 
// Cancel subscription when you want to stop receiving events 
subscription.cancel()
1
2
3
4
5
6
7
8
9
10
11
val disposable: Disposable = channelClient.subscribe { event: ChatEvent -> 
    when (event) { 
        // Check for specific event types 
        is NewMessageEvent -> { 
            val message = event.message 
        } 
    } 
} 
 
// Dispose when you want to stop receiving events 
disposable.dispose()
1
2
3
channel.on().listen((Event event) { 
  print("received a new event of type ${event.type}"); 
});

Client Events

Copied!

Not all events are specific to channels. Events such as the user's status has changed, the users' unread count has changed, and other notifications are sent as client events. These events can be listened to through the client directly:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// subscribe to all client events and log the unread_count field 
client.on(event => { 
	if (event.total_unread_count !== null) { 
		console.log(`unread messages count is now: ${event.total_unread_count}`); 
	} 
  
	if (event.unread_channels !== null) { 
		console.log(`unread channels count is now: ${event.unread_channels}`); 
	} 
}); 
 
// the initial count of unread messages is returned by client.setUser 
const user = await client.setUser(user, userToken); 
console.log(`you have ${user.me.total_unread_count} unread messages on ${user.me.unread_channels} channels.`);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Subscribe for User presence events 
client.subscribeFor( 
        new Class[]{UserPresenceChangedEvent.class}, 
        event -> { 
            // Handle change 
        } 
); 
 
// Subscribe for just the first ConnectedEvent 
client.subscribeForSingle( 
        ConnectedEvent.class, 
        event -> { 
            // Use event data 
            int unreadCount = event.getMe().getTotalUnreadCount(); 
            int unreadChannels = event.getMe().getUnreadChannels(); 
        } 
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Subscribe for user presence events. 
let subscription = Client.shared.subscribe(forEvents: [.userPresenceChanged]) { event in 
    // handle user presence changed event 
} 
// Cancel subscription when you want to stop receiving events 
subscription.cancel() 
 
// Unread count globally. 
let subscription = Client.shared.subscribeToUnreadCount { count in 
    // handle new unread count 
} 
// Cancel subscription when you want to stop receiving events 
subscription.cancel() 
 
// Unread count for a channel. 
let channel = Client.shared.channel(type: .messaging, id: "general") 
let subscription = channel.subscribeToUnreadCount { count in 
    // handle new unread count 
} 
// Cancel subscription when you want to stop receiving events 
subscription.cancel()
1
2
3
4
5
6
7
8
9
10
11
// Subscribe for User presence events 
client.subscribeFor<UserPresenceChangedEvent> { event -> 
    // Handle change 
} 
 
// Subscribe for just the first ConnectedEvent 
client.subscribeForSingle<ConnectedEvent> { event -> 
    // Use event data 
    val unreadCount = event.me.totalUnreadCount 
    val unreadChannels = event.me.unreadChannels 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// subscribe to all client events and log the unread_count field 
client.on().listen((event) => { 
	if (event.totalUnreadCount != null) { 
		print('unread messages count is now: ${event.totalUnreadCount}'); 
	} 
  
	if (event.unreadChannels !== null) { 
		print('unread channels count is now: ${event.unreadChannels}'); 
	} 
}); 
 
// the initial count of unread messages is returned by client.setUser 
final user = await client.setUser(user, userToken); 
console.log(`you have ${user.me.totalUnreadCount} unread messages on ${user.me.unreadChannels} channels.`);

Connection Events

Copied!

The official SDKs make sure that a connection to Stream is kept alive at all times and that chat state is recovered when the user's internet connection comes back online. Your application can subscribe to changes to the connection using client events.

1
2
3
4
5
6
7
client.on('connection.changed', e => { 
    if (e.online) { 
        console.log('the connection is up!'); 
    } else { 
        console.log('the connection is down!'); 
    } 
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
client.subscribeFor( 
        new Class[]{ 
                ConnectedEvent.class, 
                ConnectingEvent.class, 
                DisconnectedEvent.class 
        }, 
        (ChatEvent chatEvent) -> { 
            if (chatEvent instanceof ConnectedEvent) { 
                // Socket is connected 
            } else if (chatEvent instanceof ConnectingEvent) { 
                // Socket is connecting 
            } else if (chatEvent instanceof DisconnectedEvent) { 
                // Socket is disconnected 
            } 
        } 
);
1
2
3
4
5
6
// Get all connection states. 
let subscription = Client.shared.subscribe(forEvents: [.connectionChanged]) { event in 
    // handle new connection state event 
} 
// Cancel subscription when you want to stop receiving events 
subscription.cancel()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
client.subscribeFor( 
    ConnectedEvent::class, 
    ConnectingEvent::class, 
    DisconnectedEvent::class, 
) { event -> 
    when (event) { 
        is ConnectedEvent -> { 
            // Socket is connected 
        } 
        is ConnectingEvent -> { 
            // Socket is connecting 
        } 
        is DisconnectedEvent -> { 
            // Socket is disconnected 
        } 
    } 
}
1
2
3
4
5
6
7
client.on('connection.changed', (e) => { 
    if (e.online) { 
        print('the connection is up!'); 
    } else { 
        print('the connection is down!'); 
    } 
});

Stop Listening for Events

Copied!

It is a good practice to unregister event handlers once they are not in use anymore. Doing so will save you from performance degradations coming from memory leaks or even from errors and exceptions (i.e. null pointer exceptions)

1
2
3
4
5
6
7
8
9
10
11
// remove the handler from all client events 
// client.on('connection.changed', myClientEventHandler) 
client.off(myClientEventHandler); 
 
// remove the handler from all events on a channel 
// channel.on('connection.changed', myChannelEventHandler) 
channel.off(myChannelEventHandler); 
 
// remove the handler for all "message.new" events on the channel 
// channel.on('message.new', myChannelEventHandler) 
channel.off("message.new", myChannelEventHandler);
1
2
3
4
final Disposable disposable = client.subscribe(chatEvent -> { 
    /* ... */ 
}); 
disposable.dispose();
1
2
3
4
5
6
7
8
// Get all connection states. 
let subscription = Client.shared.subscribe(forEvents: [.connectionChanged]) { event in 
    // handle new connection state event 
} 
// Cancel subscription when you want to stop receiving events 
subscription.cancel() 
 
// For subscriptions created via a channel, subscription is cancelled when channel is deallocated
1
2
val disposable: Disposable = client.subscribe { /* ... */ } 
disposable.dispose()
1
2
3
4
5
final subscription = channel.on().listen((Event event) { 
  print("received a new event of type ${event.type}"); 
}); 
 
subscription.cancel();

Get Event History (Android only)

Copied!

It is possible to request all events in order. This can be useful to search for a specific event or to manually get all events that might have been lost during a connection loss. As the Android's low level client is stateless, it may be necessary to use this feature if you're not using the module stream-chat-android-offline to sync all the events correctly.

1
2
3
4
5
6
7
8
9
10
val cidList: List<String> = listOf("messaging:123") 
val lastSeenExample = Date() 
 
chatClient.getSyncHistory(cidList, lastSeenExample).enqueue { result -> 
    if (result.isSuccess) { 
        val events: List<ChatEvent> = result.data() 
    } else { 
        // Handle result.error() 
    } 
}
1
2
3
4
5
6
7
8
9
10
11
12
List<String> cidList = new ArrayList<>(); 
cidList.add("messaging:123"); 
 
Date lastSeenExample = new Date(); 
 
chatClient.getSyncHistory(cidList, lastSeenExample).enqueue(result -> { 
    if (result.isSuccess()) { 
        List<ChatEvent> events = result.data(); 
    } else { 
        // Handle result.error() 
    } 
})