Channel Pagination

Last Edit: Sep 22 2020

The channel query endpoint allows you to paginate the list of messages, watchers, and members for one channel. To make sure that you are able to retrieve a consistent list of messages, pagination does not work with simple offset/limit parameters but instead, it relies on passing the ID of the messages from the previous page.

For example: say that you fetched the first 100 messages from a channel and want to lead the next 100. To do this you need to make a channel query request and pass the ID of the oldest message if you are paginating in descending order or the ID of the newest message if paginating in ascending order.

Use the id_lt parameter to retrieve messages older than the provided ID and id_gt to retrieve messages newer than the provided ID.

The terms id_lt and id_gt stand for ID less than and ID greater than.

ID-based pagination improves performance and prevents issues related to the list of messages changing while you’re paginating. If needed, you can also use the inclusive versions of those two parameters: id_lte and id_gte.


// the id of the last message on the page
const lastMessageId = messages[0].id;
const result = await channel.query({
    messages: { limit: 20, id_lt: lastMessageId } ,
    members: { limit: 20, offset: 0 } ,
    watchers: { limit: 20, offset: 0 },
});
                    

final response = await channel.query(
  messagesPagination: PaginationParams(limit: 2, lessThanOrEqual: "123"),
  membersPagination:  PaginationParams(limit: 2, offset: 0),
  watchersPagination: PaginationParams(limit: 2, offset: 0),
);
                    

$messages = $channel->query([
		'messages' => ['limit'=>2, 'id_lte' => '123'], 
		'members'  => ['limit'=>2, 'offset' => 0],
		'watchers' => ['limit'=>2, 'offset' => 0]
]);
                    

let channel = Client.shared.channel(type: .messaging, id: "general")

let query = ChannelQuery(channel: channel,
                         messagesPagination: [.limit(2), .lessThanOrEqual("123")],
                         membersPagination: [.limit(2)],
                         watchersPagination: [.limit(2)])
    
Client.shared.queryChannel(query: query) { (result) in
    // handle result
}

// or

channel.query(messagesPagination: [.limit(2), .lessThanOrEqual("123")],
              membersPagination: [.limit(2)],
              watchersPagination: [.limit(2)]) { result in /* Handle result */ }
                    

val pageSize = 10

loadFirstPage()

fun loadFirstPage() {
    val firstPage = QueryChannelRequest().withMessages(pageSize)
    client.queryChannel(channelType, channelId, firstPage).enqueue { result ->
        val messages: List<Message> = result.data().messages
        if (messages.isNotEmpty() && messages.size == pageSize) {
            loadSecondPage(messages.last().id)
        } else {
            //all messages loaded
        }
    }
}

fun loadSecondPage(lastMessageId: String) {
    val firstPage = QueryChannelRequest().withMessages(Pagination.LESS_THAN, lastMessageId, pageSize)
    client.queryChannel(channelType, channelId, firstPage).enqueue { result ->
        val messages: List<Message> = result.data().messages
        if (messages.size < pageSize) {
            //all messages loaded
        } else {
            //load another page
        }
    }
}
                    

# the id of the last message on the page
last_message_id = messages[0]["id"]

# pick the parts you need; messages, members or watchers 
result = channel.query(
    messages={"limit": 50, "id_lt": last_message_id},
    members={"limit": 10, "offset": 0},
    watchers={"limit": 20, "offset": 0},
)
                    

# the id of the last message on the page
last_message_id = messages[0]["id"]

# pick the parts you need; messages, members or watchers 
result = channel.query({
    'messages' => {'limit' => 50, 'id_lt' => last_message_id},
    'members' => {'limit' => 50, 'offset' => 0},
    'watchers' => {'limit' => 50, 'offset' => 0},
})
                    

For members and watchers, we use limit and offset parameters.

Soon we will create friendlier aliases for id_lt and id_gt. Our best candidates are before_id and after_id, let us know if you have any feedback or suggestion!
The maximum number of messages that can be retrieved at once from the API is 300.