Unread messages

The Unread Message Count feature shows users how many messages they missed while offline. Once they reconnect or log into the app again, they can get the number of messages published in a given channel while they were gone.

Chat SDK stores info about the timetoken of the last message the current user read on a given channel on the lastReadMessageTimetoken property. lastReadMessageTimetoken is available on the Membership object.

This property is automatically set for a user when they first join (join()) a given channel or are invited to it (invite() and inviteMultiple()). For all further updates of this property, you must decide what user actions will trigger methods that mark messages as read in your chat app - whether that's some user interaction on UI, like scrolling, your app going offline, or any other behavior.

Requires App Context and Message Persistence

To store message timetokens on the user-channel membership relationship at PubNub, you must enable App Context and Message Persistence for your app's keyset in the Admin Portal.

Get last read message

You can access the lastReadMessageTimetoken property of the Membership object to check what is the timetoken of the last message a user read on a given channel. lastReadMessageTimetoken returns the last read message timetoken stored in the membership data between the channel and the current user. Use it to display markers on the message list denoting which messages haven't been read by the user yet.

Basic usage

Get the timetoken of the last message read by the support_agent_15 user on the support channel.

// Reference the support agent user

chat?.getUser(userId: "support_agent_15") { result in
switch result {
case let .success(user):
if let user = user {
// Get memberships for the user and filter by the support channel
user.getMemberships(filter: "channel.id == 'support'") { membershipsResult in
switch membershipsResult {
case let .success(membershipsResponse):
// Get the first membership for the support channel
if let membership = membershipsResponse.memberships.first {
print("Last read message timetoken: \(String(describing: membership.lastReadMessageTimetoken))")
} else {
print("No memberships found for the support channel.")
show all 27 lines

Get unread messages count (one channel)

getUnreadMessagesCount() returns the number of messages you didn't read on a given channel. You can display this number on UI in the channel list of your chat app.

Method signature

This method has the following signature:

membership.getUnreadMessagesCount(completion: ((Swift.Result<UInt64, Error>) -> Void)? = nil)

Input

This method doesn't take any parameters.

Output

TypeDescription
((Swift.Result<UInt64, Error>) -> Void)Retrieves from Message Persistence the number (count) of all messages unread by a given user on a given channel from the last read message. The method returns null when there is no last read message timetoken set on the MessageImpl object.

Basic usage

Get the number of all messages unread by the support_agent_15 user on the support channel.

// Reference the support agent user
chat?.getUser(userId: "support_agent_15") { userResult in
switch userResult {
case let .success(user):
if let user = user {
// Get memberships for the user and filter by the support channel
user.getMemberships(filter: "channel.id == 'support'") { membershipsResult in
switch membershipsResult {
case let .success(membershipsResponse):
// Get the first membership for the support channel
if let membership = membershipsResponse.memberships.first {
membership.getUnreadMessagesCount { unreadCountResult in
switch unreadCountResult {
case let .success(unreadCount):
if unreadCount > 0 {
show all 38 lines

Get unread messages count (all channels)

getUnreadMessagesCounts() returns info on all messages you didn't read on all joined channels. You can display this number on UI in the channel list of your chat app.

Method signature

This method has the following signature:

chat.getUnreadMessagesCount(
limit: Int? = nil,
page: PubNubHashedPage? = nil,
filter: String? = nil,
sort: [PubNub.MembershipSortField] = [],
completion: ((Swift.Result<[GetUnreadMessagesCount<ChannelImpl, MembershipImpl>], Error>) -> Void)? = nil
)

Input

ParameterTypeRequiredDefaultDescription
limitIntNo100Number of objects to return in response. The default (and maximum) value is 100.
pagePubNubHashedPageNon/aObject used for pagination to define which previous or next result page you want to fetch.
filterStringNon/aExpression used to filter the results. Returns only these unread messages whose properties satisfy the given expression. The filter language is defined here.
sort[PubNub.MembershipSortField]NolistOf()Key-value pair of a property to sort by, and a sort direction. Available options are id, name, and updated. Use asc or desc to specify the sorting direction, or specify null to take the default sorting direction (ascending). For example: {name: "asc"}. By default, the items are sorted by the last updated date.

Output

TypeDescription
((Swift.Result<[GetUnreadMessagesCount<ChannelImpl, MembershipImpl>], Error>) -> Void)completion containing the number (count) of all messages unread by a given user on all joined channels after the last read message. It returns these details: channel, membership, count.

Basic usage

Get the number of all messages unread by the support_agent_15 user on all joined channels.

// Reference the support agent user
chat?.getUser(userId: "support_agent_15") { result in
switch result {
case let .success(user):
if let user = user {
// Get unread messages counts for the user on all joined channels
chat.getUnreadMessagesCount(
filter: "user.id == 'support_agent_15'"
) { unreadMessagesResult in
switch unreadMessagesResult {
case let .success(unreadMessagesCounts):
// Handle success
unreadMessagesCounts.forEach { unreadCount in
print("Channel: \(unreadCount.channel.id), Unread messages count: \(unreadCount.count)")
}
show all 26 lines

Mark messages as read (one channel)

setLastReadMessage() and setLastReadMessageTimetoken() let you set the timetoken of the last read message on a given channel to set a timeline from which you can count unread messages. You choose on your own which user action it is bound to.

Setting the last read message for users lets you implement the Read Receipts feature and monitor which channel member read which message.

Method signature

These methods take the following parameters:

  • setLastReadMessage()

    membership.setLastReadMessage(
    message: MessageImpl,
    completion: ((Swift.Result<MembershipImpl, Error>) -> Void)? = nil
    )
  • setLastReadMessageTimetoken()

    membership.setLastReadMessageTimetoken(
    _ timetoken: Timetoken,
    completion: ((Swift.Result<MembershipImpl, Error>) -> Void)? = nil
    )

Input

ParameterTypeRequired by setLastReadMessage()Required by setLastReadMessageTimetoken()DefaultDescription
messageMessageImplYesNon/aLast read message on a given channel with the timestamp that gets added to the user-channel membership as the lastReadMessageTimetoken property.
timetokenTimetokenNoYesn/aTimetoken of the last read message on a given channel that gets added to the user-channel membership as the lastReadMessageTimetoken property.

Output

TypeDescription
((Swift.Result<MembershipImpl, Error>) -> Void)Returned MembershipImpl object updated with the lastReadMessageTimetoken parameter.

Basic usage

Set the message with the 16200000000000001 timetoken as the last read message for the support_agent_15 user on the support channel.

  • setLastReadMessage()

    // Retrieve the "support_agent_15" user
    chat?.getUser(userId: "support_agent_15") { userResult in
    switch userResult {
    case let .success(user):
    if let user = user {
    // Retrieve membership details for the "support" channel
    user.getMemberships(filter: "channel.id == 'support'") { membershipsResult in
    switch membershipsResult {
    case let .success(membershipsResponse):
    if let membership = membershipsResponse.memberships.first {
    // Retrieve the specific message with the given timetoken
    chat.getChannel(channelId: "support") { channelRes in
    switch channelRes {
    case let .success(channel):
    channel?.getMessage(timetoken: 16200000000000001) { messageResult in
    show all 53 lines
  • setLastReadMessageTimetoken()

    // Retrieve the "support_agent_15" user
    chat?.getUser(userId: "support_agent_15") { userResult in
    switch userResult {
    case let .success(user):
    if let user = user {
    // Retrieve membership details for the "support" channel
    user.getMemberships(filter: "channel.id == 'support'") { membershipsResult in
    switch membershipsResult {
    case let .success(membershipsResponse):
    if let membership = membershipsResponse.memberships.first {
    // Set the last read message timetoken
    membership.setLastReadMessageTimetoken(16200000000000001) { setResult in
    switch setResult {
    case .success:
    // Handle success
    show all 35 lines

Mark messages as read (all channels)

markAllMessagesAsRead() lets you mark as read all messages you didn't read on all joined channels.

Method signature

This method has the following signature:

chat.markAllMessagesAsRead(
limit: Int? = nil,
page: PubNubHashedPage? = nil,
filter: String? = nil,
sort: [PubNub.MembershipSortField] = [],
completion: ((Swift.Result<(memberships: [MembershipImpl], page: PubNubHashedPage?), Error>) -> Void)? = nil
)

Input

ParameterTypeRequiredDefaultDescription
limitIntNo100Number of objects to return in response. The default (and maximum) value is 100.
pagePubNubHashedPageNon/aObject used for pagination to define which previous or next result page you want to fetch.
filterStringNon/aExpression used to filter the results. Returns only these messages whose properties satisfy the given expression. The filter language is defined here.
sort[PubNub.MembershipSortField]NolistOf()Key-value pair of a property to sort by, and a sort direction. Available options are id, name, and updated. Use asc or desc to specify the sorting direction, or specify null to take the default sorting direction (ascending). For example: {name: "asc"}. By default, the items are sorted by the last updated date.

Output

TypeDescription
((Swift.Result<(memberships: [MembershipImpl], page: PubNubHashedPage?), Error>) -> Void)Returned object with a list of memberships and a page object with these fields: next, prev, total, and status.

Basic usage

Mark the total number of 50 messages as read and specify you want to fetch the results from the next page using a string that was previously returned from the PubNub server.

// Define your next page string for pagination
let nextPageString = "your_next_page_string"

/// Call to mark all messages as read on all joined channels
chat.markAllMessagesAsRead(
limit: 50,
page: PubNubHashedPageBase(start: nextPageString) // or use `PubNubHashedPage(next: nil, prev: nil)` if you are not using pagination
) { result in
switch result {
case .success(let response):
// Handle success
print("Successfully marked all messages as read.")
// Process response.memberships if needed
response.memberships.forEach { membership in
print("Channel: \(membership.channel.id) marked as read.")
show all 21 lines
Last updated on