Querying Channels

It is necessary for most applications to query the API for channels. This will retrieve a list of channels and render them in a visual list in the application. Watching channels is the process by which a user can receive real-time updates on a channel with the Stream Chat API.

Here are some tips:

  • A channel is not created in the API until one of the following methods is used on the channel instance. Each method is subtly different.
channel.create();
channel.query();
channel.watch();

Only one of these is necessary. For example, it is redundant to create a channel, if you also intend to watch that channel. The watch call automatically creates the channel in addition to watching the channel for real-time updates.

  • With client.queryChannels();, a user can watch up to 30 channels in a single API call, meaning there is no need to watch them individually or use channel.watch(); after queryChannels. Using client.queryChannels(); can substantially decrease the API calls the application has to make, reducing network traffic and improving the performance of the application when watching many channels at once.

queryChannels filters

A channel list in an application can often form the backbone of the chat experience and be one of the first views that a user sees upon opening a chat experience. As such, it is important to run an optimal filter to retrieve the channel list when needed.

A good guide is to use a filter that is as selective as possible. For example, if your filter is still going to return >50% of channels in the application, it may be problematic.

  • Avoid NOR logical operators and NIN and NOT comparison operators in the filter variable as they are not selective.

  • Filter by CID is the most performant query you can use.

  • For social messaging (DM’s, group chats, etc.), a minimum filter of type and members: {$in: userID} should be used.

// Filter by type and member (use case: social messaging)
final filter = { 'type': 'messaging', 'members': {r'$in': [userID]} };
// Filter by CID
final filter = { 'cid': channelCID };
  • Avoid overly complex queries that have >1 AND or OR statements.

  • Use custom fields on channels to make filters more simple.

  • Reach out to https://getstream.io/contact/support/ if you plan on having millions of channels and are unsure of your queryChannels filter. We’re here to help!

  • Filtering by type + channel_id is not recommended. Instead, use CID.

  • Filtering by type alone is not recommended. Instead, use CID.

// Not recommended
final filter = { 'type': 'messaging' };
// Instead, use
final filter = { 'type': 'messaging', 'members': {r'$in': [userID]} }

Using CID is always more performant than ID.

// Not recommended. For example, channel_id = "abChannel11237"
final filter = { 'id': { r'$in': [channel_id] } };
// Instead, use channel_cid. For example, channel_cid = "messaging:abChannel11237"
final filter = { 'cid': { r'$in': [channel_cid] } };

queryChannels sort

  • It is always best to use a sort parameter in the query, although we will default to updated_at. This is the more recent timestamp between Channel.create_at and Channel.last_message_at.

  • The other sort parameter that is highly optimized is last_message_at.

final sort = [SortOption('last_message_at', direction: SortOption.DESC)];

Sorting on custom fields is possible, but it does have some scalability implications. Sorting on a custom field is going to be performant up to ~2000-3000 channels. However, for Enterprise customers, this is possible for us to provide optimizations here in certain circumstances.

© Getstream.io, Inc. All Rights Reserved.