PubSubMessageListener Class - Android
Receives the messages of a topic you subscribed to. Every method has a default empty body, so override only the callbacks you need. All of them are called on the main thread.
onMessageReceived()
-
onMessageReceived()is called for each message published on the topic. -
It is called once per live message, in publish order, including the messages you publish yourself.
-
Parameter:
message— typePubSubMessage
onOldMessagesReceived()
-
onOldMessagesReceived()is called for each batch of the topic's stored messages after subscribing. -
Only messages published with
persist = trueare stored; a topic with none fires no history callback at all. -
History streams in server-paced batches; the final batch carries
info.isLastastrue. -
Subscribing with or without
PubSubSubscribeOptionsreplays history this way — the options change only how much of it is replayed, never how it is delivered. -
Parameters:
messages— typeList<PubSubMessage>, the historical messages in this batch.info— typePubSubHistoryInfo, batch metadata. See PubSubHistoryInfo.
Each call carries part of the history — append the messages to what you already hold rather than replacing it. A topic with no history fires no history callback at all, so do not wait on isLast to detect an empty topic.
onBatchReceived()
-
onBatchReceived()is called once per live batch with all messages of that batch, before the per-messageonMessageReceived()calls for the same batch. -
Override this to amortise per-message work — a single database transaction or analytics flush per batch instead of one per message.
-
Parameter:
messages— typeList<PubSubMessage>, the live messages in this batch.
Batched delivery is enabled per room by the server configuration, not by subscribe options, so your app must work with and without it. Every message of a batch also arrives on onMessageReceived(): handle each message in one callback or the other, never both, or you will count it twice. Because the callback runs on the main thread, move the work itself off it.
onMessageDrop()
-
onMessageDrop()is called when the SDK notices that the server did not deliver every live message on the topic. -
It has two causes: the server discarded messages because this subscriber fell behind (see
maxQueue), or delivery resumed after the server skipped messages, including messages over thenewMessageLimitcap. -
Parameter:
info— typePubSubMessageDropInfo. See PubSubMessageDropInfo. -
It is coalesced — one call can stand for many dropped messages. Under
RealtimeOverflow.DROP, don't rely on it to count what the policy sheds. -
Treat it as a hint that something was missed, not as a complete count. A loss is noticed only once delivery resumes, so messages dropped at the very end of a burst are never reported.
Example
val pubSubMessageListener = object : PubSubMessageListener {
override fun onMessageReceived(message: PubSubMessage) {
Log.d("#message", "onMessageReceived: ${message.message}")
}
override fun onOldMessagesReceived(messages: List<PubSubMessage>, info: PubSubHistoryInfo) {
Log.d("#message", "history batch of ${messages.size}, isLast: ${info.isLast}")
}
override fun onBatchReceived(messages: List<PubSubMessage>) {
Log.d("#message", "onBatchReceived: ${messages.size} messages")
}
override fun onMessageDrop(info: PubSubMessageDropInfo) {
Log.d("#message", "onMessageDrop: ${info.droppedCount} messages lost")
}
}
If one of these callbacks throws, the SDK catches the exception without logging it and keeps calling the other listeners. Catch and log errors inside your callbacks.
PubSubHistoryInfo
Metadata for a batch of historical messages delivered via onOldMessagesReceived().
isLast
-
type:
Boolean -
trueon the final history batch, meaning the topic's history is complete.
PubSubMessageDropInfo
Details of a message-drop event delivered via onMessageDrop().
droppedCount
-
type:
Int -
How many live messages were lost in this drop event. The event is coalesced, so one event can represent many dropped messages.
Got a Question? Ask us on discord

