Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[🐛] Bug Report Title - Duplicate Messages While Resending Failed Messages #2852

Open
Vijay-Magadum opened this issue Dec 13, 2024 · 14 comments

Comments

@Vijay-Magadum
Copy link

Vijay-Magadum commented Dec 13, 2024

Hello,
I’ve implemented offline support in my app and am resending failed messages using the retrySendMessage function from useMessagesContext. While it works, I’m seeing duplicate messages in the UI when navigating back and forth between the chat screen. However, the messages don’t have duplicate IDs in the dashboard.

Can you help me figure out why this is happening?

Thanks!
As you can see the attached Image and the Error Below:

Screenshot 2024-12-13 at 7 06 33 PM

Warning: Encountered two children with the same key, `.$7d0b3412-4b83-437a-80b8-f80d0898a52b-22e812e3-9b26-41ce-3004-b8d723302295`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
    in RCTScrollContentView (created by ScrollView)
    in RCTScrollView (created by ScrollView)
    in ScrollView (created by ScrollView)
    in ScrollView (created by VirtualizedList)
    in VirtualizedListContextProvider (created by VirtualizedList)
    in VirtualizedList (created by FlatList)
    in FlatList (created by MessageListWithContext)
    in RCTView (created by View)
    in View (created by MessageListWithContext)
    in MessageListWithContext (created by MessageList)
    in MessageList (created by ChatScreen)
    in RCTView (created by View)
    in View (created by ChatScreen)
    in RCTView (created by View)
    in View (created by ImageBackground)
    in ImageBackground (created by ChatScreen)
    in RCTView (created by View)
    in View (created by ChatScreen)
    in ChatScreen
    in Unknown (created by Route(ChatScreen))
    in Suspense (created by Route(ChatScreen))
    in Route (created by Route(ChatScreen))
    in Route(ChatScreen) (created by SceneView)
    in StaticContainer
    in EnsureSingleNavigator (created by SceneView)
    in SceneView (created by SceneView)
    in RCTView (created by View)
    in View (created by DebugContainer)
    in DebugContainer (created by MaybeNestedStack)
    in MaybeNestedStack (created by SceneView)
    in RCTView (created by View)
    in View (created by SceneView)
    in RNSScreen (created by Animated(Anonymous))
    in Animated(Anonymous) (created by InnerScreen)
    in Suspender (created by Freeze)
    in Suspense (created by Freeze)
    in Freeze (created by DelayedFreeze)
    in DelayedFreeze (created by InnerScreen)
    in InnerScreen (created by Screen)
    in Screen (created by SceneView)
    in SceneView (created by NativeStackViewInner)
    in Suspender (created by Freeze)
    in Suspense (created by Freeze)
    in Freeze (created by DelayedFreeze)
    in DelayedFreeze (created by ScreenStack)
    in RNSScreenStack (created by ScreenStack)
    in ScreenStack (created by NativeStackViewInner)
    in NativeStackViewInner (created by NativeStackView)
    in RCTView (created by View)
    in View (created by SafeAreaProviderCompat)
    in SafeAreaProviderCompat (created by NativeStackView)
    in NativeStackView (created by NativeStackNavigator)
    in PreventRemoveProvider (created by NavigationContent)
    in NavigationContent
    in Unknown (created by NativeStackNavigator)
    in NativeStackNavigator
    in Unknown (created by ChatLayout)
    in RCTView (created by View)
    in View (created by ChannelWithContext)
    in MessageInputProvider (created by ChannelWithContext)
    in SuggestionsProvider (created by ChannelWithContext)
    in ThreadProvider (created by ChannelWithContext)
    in MessagesProvider (created by ChannelWithContext)
    in PaginatedMessageListProvider (created by ChannelWithContext)
    in TypingProvider (created by ChannelWithContext)
    in OwnCapabilitiesProvider (created by ChannelWithContext)
    in ChannelProvider (created by ChannelWithContext)
    in RCTView (created by View)
    in View (created by KeyboardCompatibleView)
    in KeyboardProvider (created by KeyboardCompatibleView)
    in KeyboardCompatibleView (created by ChannelWithContext)
    in ChannelWithContext (created by Channel)
    in Channel (created by ChatLayout)
    in ChatLayout
    in Unknown (created by Route(chatScreen))
    in Suspense (created by Route(chatScreen))
    in Route (created by Route(chatScreen))
    in Route(chatScreen) (created by SceneView)
    in StaticContainer
    in EnsureSingleNavigator (created by SceneView)
    in SceneView (created by SceneView)
    in RCTView (created by View)
    in View (created by DebugContainer)
    in DebugContainer (created by MaybeNestedStack)
    in MaybeNestedStack (created by SceneView)
    in RCTView (created by View)
    in View (created by SceneView)
    in RNSScreen (created by Animated(Anonymous))
    in Animated(Anonymous) (created by InnerScreen)
    in Suspender (created by Freeze)
    in Suspense (created by Freeze)
    in Freeze (created by DelayedFreeze)
    in DelayedFreeze (created by InnerScreen)
    in InnerScreen (created by Screen)
    in Screen (created by SceneView)
    in SceneView (created by NativeStackViewInner)
    in Suspender (created by Freeze)
    in Suspense (created by Freeze)
    in Freeze (created by DelayedFreeze)
    in DelayedFreeze (created by ScreenStack)
    in RNSScreenStack (created by ScreenStack)
    in ScreenStack (created by NativeStackViewInner)
    in NativeStackViewInner (created by NativeStackView)
    in RCTView (created by View)
    in View (created by SafeAreaProviderCompat)
    in SafeAreaProviderCompat (created by NativeStackView)
    in NativeStackView (created by NativeStackNavigator)
    in PreventRemoveProvider (created by NavigationContent)
    in NavigationContent
    in Unknown (created by NativeStackNavigator)
    in NativeStackNavigator
    in Unknown (created by ModelLayout)
    in ModelLayout
    in Unknown (created by Route((models)))
    in Suspense (created by Route((models)))
    in Route (created by Route((models)))
    in Route((models)) (created by SceneView)
    in StaticContainer
    in EnsureSingleNavigator (created by SceneView)
    in SceneView (created by SceneView)
    in RCTView (created by View)
    in View (created by DebugContainer)
    in DebugContainer (created by MaybeNestedStack)
    in MaybeNestedStack (created by SceneView)
    in RCTView (created by View)
    in View (created by SceneView)
    in RNSScreen (created by Animated(Anonymous))
    in Animated(Anonymous) (created by InnerScreen)
    in Suspender (created by Freeze)
    in Suspense (created by Freeze)
    in Freeze (created by DelayedFreeze)
    in DelayedFreeze (created by InnerScreen)
    in InnerScreen (created by Screen)
    in Screen (created by SceneView)
    in SceneView (created by NativeStackViewInner)
    in Suspender (created by Freeze)
    in Suspense (created by Freeze)
    in Freeze (created by DelayedFreeze)
    in DelayedFreeze (created by ScreenStack)
    in RNSScreenStack (created by ScreenStack)
    in ScreenStack (created by NativeStackViewInner)
    in NativeStackViewInner (created by NativeStackView)
    in RCTView (created by View)
    in View (created by SafeAreaProviderCompat)
    in SafeAreaProviderCompat (created by NativeStackView)
    in NativeStackView (created by NativeStackNavigator)
    in PreventRemoveProvider (created by NavigationContent)
    in NavigationContent
    in Unknown (created by NativeStackNavigator)
    in NativeStackNavigator
    in Unknown (created by StackScreens)
    in StackScreens (created by RootLayoutNav)
    in SelectedChannelProvider (created by RootLayoutNav)
    in ActiveChannelsProvider (created by ChannelsStateProvider)
    in ChannelsStateProvider (created by ChatWithContext)
    in ThemeProvider (created by ChatWithContext)
    in TranslationProvider (created by ChatWithContext)
    in ChatProvider (created by ChatWithContext)
    in ChatWithContext (created by Chat)
    in Chat (created by GetStreamChatComponent)
    in ImageGalleryProvider (created by OverlayProvider)
    in AttachmentPickerProvider (created by OverlayProvider)
    in MessageOverlayProvider (created by OverlayProvider)
    in TranslationProvider (created by OverlayProvider)
    in OverlayProvider (created by GetStreamChatComponent)
    in RCTView (created by View)
    in View (created by GestureHandlerRootView)
    in GestureHandlerRootView (created by GetStreamChatComponent)
    in GetStreamChatComponent (created by RootLayoutNav)
    in SelectedDataProvider (created by RootLayoutNav)
    in ApiDataProvider (created by RootLayoutNav)
    in UserAuthProvider (created by RootLayoutNav)
    in UserNetworkProvider (created by RootLayoutNav)
    in ThemeProvider (created by PaperProvider)
    in RCTView (created by View)
    in View (created by Portal.Host)
    in Portal.Host (created by PaperProvider)
    in RCTView (created by View)
    in View (created by SafeAreaInsetsContext)
    in SafeAreaProviderCompat (created by PaperProvider)
    in PaperProvider (created by RootLayoutNav)
    in RootLayoutNav (created by RootLayout)
    in RootLayout
    in Try
    in Unknown
    in Unknown (created by Route())
    in Suspense (created by Route())
    in Route (created by Route())
    in Route() (created by ContextNavigator)
    in RNCSafeAreaProvider (created by SafeAreaProvider)
    in SafeAreaProvider (created by wrapper)
    in wrapper (created by ContextNavigator)
    in EnsureSingleNavigator
    in BaseNavigationContainer
    in ThemeProvider
    in NavigationContainerInner (created by ContextNavigator)
    in ContextNavigator (created by ExpoRoot)
    in ExpoRoot (created by App)
    in App (created by ErrorOverlay)
    in ErrorToastContainer (created by ErrorOverlay)
    in ErrorOverlay (created by withDevTools(ErrorOverlay))
    in withDevTools(ErrorOverlay)
    in RCTView (created by View)
    in View (created by AppContainer)
    in RCTView (created by View)
    in View (created by AppContainer)
    in AppContainer
    in main(RootComponent)

@Vijay-Magadum
Copy link
Author

This is my below code that I have implemented inside my ChatScreen.tsx where I am integrating my chat screen under Channel component. below is the main logic I am implementing.


const { retrySendMessage } = useMessagesContext();
const { networkStatus } = useNetworkContext();

const sendFailedMessages = async () => {
  messageList["processedMessageList"].map(async (message: any) => {
    if (message.status === MessageStatus.FAILED) {
      try {
        await retrySendMessage(message);
      } catch (error) {
        console.error("Error sending failed messages:", error);
      }
    }
  });
};

useEffect(() => {
  if (networkStatus) sendFailedMessages();
}, [networkStatus]);



@khushal87
Copy link
Member

Hey @Vijay-Magadum, what's your stream-chat-react-native version?

@Vijay-Magadum
Copy link
Author

Hey @Vijay-Magadum, what's your stream-chat-react-native version?

I am actually using "stream-chat-expo": "^5.41.2"

@Vijay-Magadum
Copy link
Author

hey @khushal87, have you found anything regarding this issue?

@khushal87
Copy link
Member

Hey @Vijay-Magadum, we automatically handle the resend of the failed messages when clicking the resend button on the message actions when there are no network conditions, and when it recovers, so I don't think you need to do that from your side explicitly. Currently, we don't have a way to stop the behaviour but the default should work well for you. Did you face any issues with that?

@Vijay-Magadum
Copy link
Author

hey @khushal87, I have implemented a resend message logic for failed messages. When you tap on a failed message, it resends the message. However, if I have 8-9 failed messages and tap on them simultaneously to resend, I encounter an issue where duplicate messages are being sent.

@khushal87
Copy link
Member

Instead of iterating through the failed messages like this:

 messageList["processedMessageList"].map(async (message: any) => {
    if (message.status === MessageStatus.FAILED) {
      try {
        await retrySendMessage(message);
      } catch (error) {
        console.error("Error sending failed messages:", error);
      }
    }
  });

Can you first filter out all the failed message and then iterate over only the failed messages to send them back?

@Vijay-Magadum
Copy link
Author

I have tried that as well but it was giving same error

@khushal87
Copy link
Member

This is because when the connection recovers, we add the failed messages to the message list, and when you click on the button, it might add those duplicate copies as well. Can you rely on the resend button of the Message action for this and send individual messages one at a time?

@Vijay-Magadum
Copy link
Author

Vijay-Magadum commented Dec 24, 2024

Our requirement was to send messages offline with a single tick, similar to WhatsApp, and have them automatically delivered to the other user when the device goes online. However, it seems this functionality is not currently supported in GetStream. As a result, we decided to implement automatic resending of failed messages when the device regains an internet connection. So is there any alternative way to achieve this?

@khushal87
Copy link
Member

I can't think of any without any added customization to the SDK. Maybe you can track for which messages are already sent after you recover the internet and make sure it's not resent again somehow. Are there copies for all the failed messages in the chat or its only for a few of them? And do they persist after you refresh?

@Vijay-Magadum
Copy link
Author

Okay, I will check and get back to you. For failed messages, for example, if I send numbers 1 to 9 as individual messages and try to resend them automatically, the message order becomes random, and some messages are duplicated and they persist even after refresh.

@khushal87
Copy link
Member

khushal87 commented Dec 24, 2024

Interesting. We made some improvements in the behaviour of the message list in v6, but that upgrade would be a lot for you just to fix this issue, so I would not say that it might solve your problem.

@Vijay-Magadum
Copy link
Author

Okay, I will check that as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants