Incorrect message retrieval when using cursor pagination in Nakama chat

Hello. An issue has occurred while developing chat functionality using Nakama. We are currently implementing a feature that allows users to move to the channel list and join a new channel without leaving the existing chat channel. To achieve this, we designed it to save the cursor of the existing channel before moving to the list, so that when returning to the channel, users can continue chatting from the last message they checked. After saving the cursor and confirming the last received message, we moved to the list, sent a message to the channel, and checked messages from the saved cursor position. However, errors are occurring where either older messages are being retrieved instead of the most recent ones, or the next_cursor is returning the same value as the previous cursor. Below are the environment and functions used.

registry.heroiclabs.com/heroiclabs/nakama:3.26.0

@heroiclabs/nakama-js”: “^2.8.0”

async function setCursor() {
  var result = await client.listChannelMessages(session, channel_id, 1, false)
  cursor = result.cacheable_cursor
  result.messages.forEach((message) => {
    console.log("Message has id %o and content %o", message.message_id, message.data);
  });
}

async function listMessages() {
  var result = await client.listChannelMessages(session, channel_id, 50, true, cursor)
  cursor = result.next_cursor
  result.messages.forEach((message) => {
    console.log("Message has id %o and content %o", message.message_id, message.data);
  });
}

Hello @rokky,

I believe this issue is fixed on the master branch, for now, you can either build Nakama from source from master, or check if downgrading to 3.25.0 helps.

Best.

Thank you for your response. I have checked both versions 3.26.0 and 3.25.0, but the error of retrieving messages older than the cursor position remains unresolved. Through testing, I discovered that when the message transmission interval is larger, the cursor ensures relatively accurate positioning. After analyzing this, I found out something important. When there are consecutive messages with the same create time value prior to the cursor-designated message, the system retrieves all messages with that create time. This explains why the cursor accuracy improves as the message transmission interval increases. Due to my limited understanding of the DB structure, I’m not sure if this is intended behavior, but currently, using the cursor is proving difficult.

I have one more question. When using next_cursor to fetch messages with different creation times, I’m wondering if it is intended behavior to retrieve messages starting from the last message of the previous cursor.
For example, if messages are indexed in the order they were created and retrieved in batches of 10, the first batch fetches messages from index 0 to 9. However, instead of retrieving messages from 10 to 19 in the next batch, it fetches from 9 to 18, and then from 18 to 27 in the following batch. This causes the last message of the previous batch to be duplicated in the next batch. Could you confirm whether this is a bug or the expected behavior?

I just ran a quick test on master and I believe that all of these issues are fixed and will be part of the next release. If you try to run your tests on master you should observe the same.

Otherwise you’ll have to wait for the next release, apologies for the inconvenience.