Select your Platform:
Client SDKs
Backend SDKs
Channel Pagination
Confused about "Channel Pagination"?
Let us know how we can improve our documentation:
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
.
1
2
3
4
5
6
7
// 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 },
});
1
2
3
4
5
final response = await channel.query(
messagesPagination: PaginationParams(limit: 2, lessThanOrEqual: "123"),
membersPagination: PaginationParams(limit: 2, offset: 0),
watchersPagination: PaginationParams(limit: 2, offset: 0),
);
1
2
3
4
5
$messages = $channel->query([
'messages' => ['limit'=>2, 'id_lte' => '123'],
'members' => ['limit'=>2, 'offset' => 0],
'watchers' => ['limit'=>2, 'offset' => 0]
]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// messages
let controller = chatClient.channelController(for: .init(type: .messaging, id: "general"))
controller.loadNextMessages(limit: 25) { error in
if let error = error {
// handle error
print(error)
} else {
// access messages
print(controller.messages)
controller.loadNextMessages(limit: 25) { error in
// handle error / access messages
print(error ?? controller.messages)
}
}
}
// members
let memberController = chatClient.memberListController(query: .init(cid: .init(type: .messaging, id: "general")))
memberController.loadNextMembers(limit: 25) { error in
if let error = error {
// handle error
print(error)
} else {
// access members
print(memberController.members)
memberController.loadNextMembers(limit: 25) { error in
// handle error / access members
print(error ?? memberController.members)
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
val channelClient = client.channel("messaging", "general")
val pageSize = 10
// Request for the first page
val request = QueryChannelRequest()
.withMessages(pageSize)
channelClient.query(request).enqueue { result ->
if (result.isSuccess) {
val messages: List<Message> = result.data().messages
if (messages.size < pageSize) {
// All messages loaded
} else {
// Load next page
val nextRequest = QueryChannelRequest()
.withMessages(LESS_THAN, messages.last().id, pageSize)
// ...
}
} else {
// Handle result.error()
}
}
1
2
3
4
5
6
7
8
9
# 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},
)
1
2
3
4
5
6
7
8
9
# 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},
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ChannelClient channelClient = client.channel("messaging", "general");
int pageSize = 10;
// Request for the first page
QueryChannelRequest request = new QueryChannelRequest()
.withMessages(pageSize);
channelClient.query(request).enqueue(result -> {
if (result.isSuccess()) {
List<Message> messages = result.data().getMessages();
if (messages.size() < pageSize) {
// All messages loaded
} else {
// Load next page
Message lastMessage = messages.get(messages.size() - 1);
QueryChannelRequest nextRequest = new QueryChannelRequest()
.withMessages(LESS_THAN, lastMessage.getId(), pageSize);
// ...
}
} else {
// Handle result.error()
}
});
For members and watchers, we use limit
and offset
parameters.