MessageCollection loading and event handler issues

Hi, we are having some problems using the MessageCollection.

This is how we set up the message collection

this.messageCollection = channel.createMessageCollection()
	.setStartingPoint(Number.MAX_VALUE)
	.setLimit(3) // using a smaller limit for testing purpose
	.build();

When doing loadPrevious(), duplicated messages are returned.

Imagine I have a total of 10 messages in a channel, this is how the loading behaves now:

  • 1st load returns [message8, message9, message10]
  • 2nd load returns [message5, message6, message7, message8]
  • 3rd load returns [message2, message3, message4, message5]
  • 4th load returns [message1, message2]

As you can see, each subsequent load returns 1 message more that the specified limit (3) and is the same message as the last returned message.
I’m wondering if this is intended or not?


Another question regarding MessageCollectionHandler.

  1. When receiving new messages in the channel, the onMessagesAdded handler is not triggered at all
  2. When the current user sends a message to the channel, onMessagesAdded is triggered and immediately followed by onMessagesDeleted, causing the new message to be shown the the user for around 1 second and immediately disappear. Also, the message received in onMessagesAdded and onMessagesDeleted has a messageId of 0, and a sendingStatus of "pending"

This is the pseudocode of my implementation

const messageCollectionHandler: MessageCollectionHandler = {
	onMessagesAdded: (_, channel, messages) => {
		console.log('added', messages);
		messages.map(message => dispatch(addMessage(message)));
	},
	onMessagesUpdated: (_, channel, messages) => {
		console.log('updated', messages);
		messages.map(message => dispatch(updateMessage(message)));
	},
	onMessagesDeleted: (_, channel, messages) => {
		console.log('deleted', messages)
		messages.map((message) => dispatch(deleteMessage(message.messageId)));
	},
	onChannelUpdated: () => {},
	onChannelDeleted: () => {},
	onHugeGapDetected: () => {},
};

@hewong
I’m sorry for the late response.

the first question

  • Limit is the limit for API server fetch. If load previous called(pre limit = 3, next limit = 0), the overlapping message is next limit = 0, which includes itself. So for the same message please update the existing message in the app layer.

the second question

  • When I try it, it seems like Message Collection Handler added is working well. Is this really not called? (please check once again)

thanks.

Hi, may I know which SDK version did you use please? Also, do you mind sharing an example of how you setup the MessageCollectionHandler? Including building and initializing the message collection.

Thank you!

I checked with our basic sample.

Hi, after a few rounds of debugging, we found that the event handler issues that happened on our end is related to how we build the MessageCollection.

  1. If we use Date.now() as the startingPoint, the event handler works correctly, but loadPrevious() breaks. Let’s say we set 30 as the pagination limit, the first load returns 30 messages and second load returns 31 messages. But the last 16 messages from the first load overlaps with the first 16 messages from the second load. And if I console.log(messageCollection), the property _messages has only 45 messages instead of 60. We’ve tested with 50 as the limit, and the number of overlapping messages is 26. So it seems like it’s always half of the limit.

  2. If I use Number.MAX_VALUE as the startingPoint, the event handler does not work correctly, as mentioned above in the topic. However, the loading works fine. Where there is only one overlapping message between first and second loads, which according to your explanation, is the expected behaviour. Also console.log indicates that messageCollection._messages contains 60 messages.

In short:

  • Date.now() as starting point
    • event handler works
    • loading breaks
  • Number.MAX_VALUE as starting point
    • event handler breaks
    • loading works

Could you help investigate on this please?
FYI we are using sendbird sdk v3.1.16 and react native v0.66.4

@hewong I will check it with our SDK team and get back to here, thank you for your debugging,

@hewong

Hi there. I’m not able to reproduce the issue you talk about for v3.1.17. I have a working example for you here - misty-leftpad-jjo52h - CodeSandbox

One thing I would mention is please be careful when using React. Sendbird’s objects are mutable and are passed by reference not value. On the other hand, React’s common case is that there is an expectation of immutable state.

Please try out your app in my sample. I have also added additional guidance comments in the sample.

I’m sorry our docs are not clear about what is happening where. I will see if I can get some updates for our docs.

Ahh, the additional comment on how onApiResult internally calls loadPrevious and loadNext makes it much clearer. The doc was a little bit vague on what onApiResult does other than fetching messages.

I was explicitly calling loadPrevious() after the initialization, and it caused some race conditions where onApiResult (probably executed asynchronously) returns the messages after loadPrevious(), so I think that’s why I was getting duplicated messages. It would be nice to be able to wait for onApiResult to finish before proceeding though :smile:

Thank you so much for the patience! :pray: