val channelClient = client.channel("messaging", "general")
val pageSize = 10
// Request the first page
val request = QueryChannelRequest()
.withMessages(pageSize)
channelClient.query(request).enqueue { result ->
if (result is Result.Success) {
val messages: List<Message> = result.value.messages
if (messages.size < pageSize) {
// All messages loaded
} else {
// Load next page using the oldest message ID
val nextRequest = QueryChannelRequest()
.withMessages(Pagination.LESS_THAN, messages.last().id, pageSize)
// ...
}
} else {
// Handle Result.Failure
}
}Channel Pagination
The channel query endpoint allows you to paginate messages, watchers, and members for a channel. Messages use ID-based pagination for consistency, while members and watchers use offset-based pagination.
Message Pagination
Message pagination uses ID-based parameters rather than simple offset/limit. This approach improves performance and prevents issues when the message list changes while paginating.
For example, if you fetched the first 100 messages and want to load the next 100, pass the ID of the oldest message (when paginating in descending order) or the newest message (when paginating in ascending order).
Pagination Parameters
| Parameter | Description |
|---|---|
id_lt | Retrieve messages older than (less than) the ID |
id_gt | Retrieve messages newer than (greater than) the ID |
id_lte | Retrieve messages older than or equal to the ID |
id_gte | Retrieve messages newer than or equal to the ID |
id_around | Retrieve messages around a specific message ID |
// Get the ID of the oldest message on the current page
const lastMessageId = messages[0].id;
// Fetch older messages
const result = await channel.query({
messages: { limit: 20, id_lt: lastMessageId },
});
// Fetch messages around a specific message
const result = await channel.query({
messages: { limit: 20, id_around: messageId },
});let messageId: MessageId = "123"
let channelId = ChannelId(type: .messaging, id: "general")
let controller = chatClient.channelController(for: channelId)
// Load messages around a specific message (id_around)
controller.loadPageAroundMessageId(messageId) { error in
if let error = error {
print(error)
} else {
print(controller.messages)
// Load newer messages (id_gt)
controller.loadNextMessages(limit: 10) { error in
print(error ?? controller.messages)
// Load older messages (id_lt)
controller.loadPreviousMessages(limit: 10) { error in
print(error ?? controller.messages)
}
}
}
}
// Alternative: Use Chat for more granular control
let chat = chatClient.makeChat(for: channelId)
// Messages newer than ID (id_gt)
let newerMessages = try await chat.loadMessages(after: messageId, limit: 10)
// Messages older than ID (id_lt)
let olderMessages = try await chat.loadMessages(before: messageId, limit: 10)
// Messages around ID (id_around)
let aroundMessages = try await chat.loadMessages(around: messageId, limit: 10)final response = await channel.query(
messagesPagination: PaginationParams(limit: 20, lessThan: lastMessageId),
);from getstream.models import MessagePaginationParams
# Get the ID of the oldest message on the current page
last_message_id = messages[0]["id"]
# Fetch older messages
result = channel.get_or_create(
messages=MessagePaginationParams(limit=50, id_lt=last_message_id),
)
# Fetch messages around a specific message
result = channel.get_or_create(
messages=MessagePaginationParams(limit=20, id_around=message_id),
)require 'getstream_ruby'
Models = GetStream::Generated::Models
# Get the ID of the oldest message on the current page
last_message_id = messages[0]['id']
# Fetch older messages
result = client.chat.get_or_create_channel('messaging', 'general',
Models::ChannelGetOrCreateRequest.new(
messages: Models::MessagePaginationParams.new(limit: 50, id_lt: last_message_id)
)
)
# Fetch messages around a specific message
result = client.chat.get_or_create_channel('messaging', 'general',
Models::ChannelGetOrCreateRequest.new(
messages: Models::MessagePaginationParams.new(limit: 50, id_around: message_id)
)
)using GetStream;
using GetStream.Models;
var client = new StreamClient("{{ api_key }}", "{{ api_secret }}");
var chat = new ChatClient(client);
// Get the ID of the oldest message on the current page
var lastMessageId = messages[0].ID;
// Fetch older messages
var resp = await chat.GetOrCreateChannelAsync("messaging", "general",
new ChannelGetOrCreateRequest
{
Messages = new MessagePaginationParams { Limit = 50, IDLt = lastMessageId }
});use GetStream\ChatClient;
use GetStream\GeneratedModels as Models;
$response = $client->getOrCreateChannel("messaging", "general", new Models\ChannelGetOrCreateRequest(
messages: new Models\MessagePaginationParams(limit: 20, idLt: $lastMessageId),
));channel := client.Chat().Channel("messaging", "general")
// Fetch older messages using the oldest message ID
channel.GetOrCreate(ctx, &getstream.GetOrCreateChannelRequest{
Messages: &getstream.MessagePaginationParams{
Limit: getstream.PtrTo(50),
IDLt: getstream.PtrTo(lastMessageID),
},
})
// Fetch messages around a specific message
channel.GetOrCreate(ctx, &getstream.GetOrCreateChannelRequest{
Messages: &getstream.MessagePaginationParams{
Limit: getstream.PtrTo(20),
IDAround: getstream.PtrTo(messageID),
},
})// Android SDK
ChannelClient channelClient = client.channel("messaging", "general");
int pageSize = 10;
// Request 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 using the oldest message ID
Message lastMessage = messages.get(messages.size() - 1);
QueryChannelRequest nextRequest = new QueryChannelRequest()
.withMessages(LESS_THAN, lastMessage.getId(), pageSize);
// ...
}
} else {
// Handle result.error()
}
});
// Backend SDK
String lastMessageId = lastMessage.getId();
chat.getOrCreateChannel("type", "id", GetOrCreateChannelRequest.builder()
.messages(MessagePaginationParams.builder()
.idLt(lastMessageId)
.build())
.build()).execute();FMessagePaginationOptions MessagesPagination;
MessagesPagination.Limit = 20;
MessagesPagination.IdLt = LastMessageId;
Channel->Query(EChannelFlags::State, MessagesPagination, {}, {});// Channel loads with the most recent messages
var channel = await Client.GetOrCreateChannelWithIdAsync(ChannelType.Messaging, channelId: "my-channel-id");
// Load older messages
await channel.LoadOlderMessagesAsync();Member and Watcher Pagination
Members and watchers use limit and offset parameters for pagination.
| Parameter | Description | Maximum |
|---|---|---|
limit | Number of records to return | 300 |
offset | Number of records to skip | 10000 |
// Paginate members and watchers
const result = await channel.query({
members: { limit: 20, offset: 0 },
watchers: { limit: 20, offset: 0 },
});
const result = await channel.query({
state: true,
members: { limit: 110, offset: 0 },
});final response = await channel.query(
membersPagination: PaginationParams(limit: 20, offset: 0),
watchersPagination: PaginationParams(limit: 20, offset: 0),
);from getstream.models import PaginationParams
# Paginate members and watchers
result = channel.get_or_create(
members=PaginationParams(limit=20, offset=0),
watchers=PaginationParams(limit=20, offset=0),
)
result = channel.get_or_create(
state=True,
members=PaginationParams(limit=110, offset=0),
)require 'getstream_ruby'
Models = GetStream::Generated::Models
# Paginate members and watchers
result = client.chat.get_or_create_channel('messaging', 'general',
Models::ChannelGetOrCreateRequest.new(
members: Models::PaginationParams.new(limit: 20, offset: 0),
watchers: Models::PaginationParams.new(limit: 20, offset: 0)
)
)
result = client.chat.get_or_create_channel('messaging', 'general',
Models::ChannelGetOrCreateRequest.new(
state: true,
members: Models::PaginationParams.new(limit: 110, offset: 0)
)
)// Paginate members and watchers
var resp = await chat.GetOrCreateChannelAsync("messaging", "general",
new ChannelGetOrCreateRequest
{
Members = new PaginationParams { Limit = 20, Offset = 0 },
Watchers = new PaginationParams { Limit = 20, Offset = 0 }
});use GetStream\ChatClient;
use GetStream\GeneratedModels as Models;
$response = $client->getOrCreateChannel("messaging", "general", new Models\ChannelGetOrCreateRequest(
members: new Models\PaginationParams(limit: 20, offset: 0),
watchers: new Models\PaginationParams(limit: 20, offset: 0),
));channel := client.Chat().Channel("messaging", "general")
// Paginate members and watchers
channel.GetOrCreate(ctx, &getstream.GetOrCreateChannelRequest{
Members: &getstream.PaginationParams{Limit: getstream.PtrTo(20), Offset: getstream.PtrTo(0)},
Watchers: &getstream.PaginationParams{Limit: getstream.PtrTo(20), Offset: getstream.PtrTo(0)},
})const FUserPaginationOptions MemberPagination{20, 0};
const FUserPaginationOptions WatcherPagination{20, 0};
Channel->Query(EChannelFlags::State, {}, MemberPagination, WatcherPagination);To retrieve filtered and sorted members in a channel use the Query Members API