sendbird-chat-sample-react icon indicating copy to clipboard operation
sendbird-chat-sample-react copied to clipboard

multiple message in chat group

Open Harshit2307 opened this issue 3 years ago • 6 comments

while chating on channel group it is showing unnecessary multiple message in chat , here in these picture you can see i have send single message but it is appearing twice to reciever and sometime more than that Screenshot from 2022-08-19 17-02-18 Screenshot from 2022-08-19 17-02-54

Harshit2307 avatar Aug 17 '22 08:08 Harshit2307

@AAPK-code any suggestions on this ?

deepakgupta-unthinkable avatar Aug 26 '22 08:08 deepakgupta-unthinkable

I have been looking at improvements to this sample repo and believed cam across the probably cause of this issue.

Basically it was down to event handlers being duplicated as a user navigates between channels.

I have implemented the fix for this and am currently applying that fix to all sample files. Expect the updated code to be available in Github at some point in the next few days.

james-a-rob avatar Sep 29 '22 11:09 james-a-rob

@james-a-rob Any update here? We're seeing this after upgrading to v4. Even if we explicitly remove pending messages, the pending message sneaks back in. I believe this to be deeper than just a duplicate handler issue. I think Sendbird v4 is adding pending messages back into a message collection despite them being fully sent. our fix was detecting duplicate messages by reqId, and if we saw two with the same reqId, filtering out the one which messageId = 0 (the pending message). It's horrible, but we need it to remove these duplicate messages.

princefishthrower avatar Nov 02 '22 07:11 princefishthrower

plase give me a solution

Leeselbin avatar Jan 03 '23 10:01 Leeselbin

@james-a-rob
where can i find that code?

Leeselbin avatar Jan 03 '23 11:01 Leeselbin

@Leeselbin - did you see my comment? The code (in our case within a Redux reducer) looks like this:

messagesUpdated: (
      state: MessagesState,
      action: PayloadAction<{
        channel: BaseChannel;
        messages: Array<BaseMessage>;
      }>,
    ) => {
      const {messages} = action.payload;
      const combinedMessages = [...state.messages, ...messages];
      let uniqueMessages = arrayUniqueByKey(
        combinedMessages,
        'messageId',
      ).sort(sortByCreatedAt);

      const pendingMessage = uniqueMessages.find(
        (message) => message.messageId === 0,
      );

      const dualMessages = uniqueMessages.filter((message) => {
        if (message.isUserMessage() && pendingMessage?.isUserMessage()) {
          return message.reqId === pendingMessage.reqId;
        }
      });

      // i don't like this but somehow it is needed to remove the pending message
      // i believe this to be a bug in sendbird v4
      if (dualMessages.length === 2) {
        uniqueMessages = uniqueMessages.filter(message => message.messageId !== 0);
      }

      for (var i = 0; i < uniqueMessages.length - 1; i++) {
        const messageOne = uniqueMessages[i];
        const messageTwo = uniqueMessages[i + 1];
        if (
          messageOne.isUserMessage() &&
          messageTwo.isUserMessage() &&
          uniqueMessages[i].isUserMessage()
        ) {
          (uniqueMessages[i] as IExtendedUserMessage).hasSameSenderAbove =
            messageOne.sender.userId === messageTwo.sender.userId;
          continue;
        }
        (uniqueMessages[i] as IExtendedUserMessage).hasSameSenderAbove = false;
      }
      state.messages = uniqueMessages as Array<IExtendedUserMessage>;
    }

arrayUniqueByKey is a util function we had:

export const arrayUniqueByKey = <T>(array: Array<T>, key: keyof T): Array<T> => {
  return [...new Map(array.map((item) => [item[key], item])).values()];
};

princefishthrower avatar Jan 03 '23 11:01 princefishthrower