React-native-gifted-chat: Messages are completely disorganized | Not ordered.

Created on 18 Sep 2016  路  9Comments  路  Source: FaridSafi/react-native-gifted-chat

Issue Description

I'm attempting to use GiftedChat in the react-native port of our application and we're running into problems with the order in which messages are displayed, shown in a screenshot below. All of our dates are stored in MIlliseconds since UTC on the Server, porting our messages over looks like so:

var altered = {
                _id: message.key,
                text: message.data,
                createdAt: new Date(message.created_at), // Also tried just message.created_at
                user: {
                    _id: message.sender,
                    name: match.other_user.first_name,
                    avatar: match.other_user.photo
                }
            }

            giftedMessages.push(altered)

The result is this jumbled mess, it doesn't seem to follow any type of organization. This is a real conversation pulled from our database between two users, one being a test account of ours. We use Firebase, so the timestamp is stored in MIlliseconds since epoch.

gifted-confusion

Steps to Reproduce / Code Snippets

Just use the example and any dates formed using milliseconds. (IE: Date.now())

Expected Results

Proper ordering of messages.

Additional Information

  • React Native version: 0.33.0
  • react-native-gifted-chat version: 0.0.10
  • Platform(s) (iOS, Android, or both?): iOS (Don't have android)

Most helpful comment

I really appreciate this library being open sourced, but the fact that there isn't some sort of default sorting should be advertised on the readme. That is a crucial and integral part of any messaging template. Again, not saying that there needs to be a PR for this, but for the sake of users it would be nice to specify this lack of functionality more clearly upfront.

All 9 comments

We tried using ES6 Sets to determine the difference between a cached and current object containing all of our messages mapped to the key stored in our database, then using GiftedChat.append(previousState.messages, newMessages) to counteract this problem instead of rebuilding the whole array. This did not work, here's an example:

filterNewMessages(updatedMessages) {
        const oldKeys = Object.keys(this.cachedMessages)
        const oldSet = new Set(oldKeys)
        const newKeys = Object.keys(updatedMessages)

        const difference = [...new Set([...newKeys].filter(x => !oldSet.has(x)))]
        console.warn(difference)
        return difference
    }

    convertMessagesToGifted(props, added) {
        props = props || this.props
        const { selected, messages, matches } = props
        const match = matches[selected]
        if(messages == null) return
        const messagesToAppend = this.filterNewMessages(messages)

        var giftedMessages = []
        for(var i = 0; i < messagesToAppend.length; i++) {
            const messageToAppend = messages[messagesToAppend[i]]
            if(messageToAppend == null) continue

            var giftedMessage = {
                _id: messageToAppend.key,
                text: messageToAppend.data,
                createdAt: new Date(messageToAppend.created_at),
                user: {
                    _id: messageToAppend.sender,
                    name: match.other_user.first_name,
                    avatar: match.other_user.photo
                }
            }

            giftedMessages.push(giftedMessage)
        }

        // Note: May need to add the messages in order..? 馃槩
        this.setState((previousState) => {
            return {
                messages: GiftedChat.append(previousState.messages, giftedMessages)
            }
        })

        this.cachedMessages = messages
    }

Where once again message.created_at is a millisecond value, similar to that of Date.now() Considering the examples wrap Date.UTC which returns a millisecond value, passing new Date(millis) should work fine, however ordering is still really jank.

@FaridSafi Could you check to see if we're doing something incorrectly?

EDIT: Where my comment about manually ordering the array before appending them is, using this seems to fix the issue at first.

giftedMessages = giftedMessages.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())

However the problem is much more complex than that. Consider a network disconnection in which the client receives a message that was sent in the past. There's no way to append the message to GiftedChat while in the chat screen without redrawing the entire chat window, which is simply not efficient. Granted the scope of this issue is relatively small, ordering by createdAt should be a feature by default. In what chat application are the messages not ordered by the date they're sent.

Assuming the fact that you'll only ever get the "next" message from the server seems practical, but is not always the case, for example with Firebase you sync all objects after a period. IE:

Obtain all messages after 7:20 PM, Sep. 17 2016

A message sent at 7:26PM and a message sent a 7:23PM could easily get mixed around in the event of network disturbance, where 7:23PM is received last, and with the way append works, the 7:23PM message is considered newer than the 7:26PM message.

@qualifyapp GiftedChat will not sort the message for you, it will preserve the order of message as it was in the messages prop
Hope that helps

I really appreciate this library being open sourced, but the fact that there isn't some sort of default sorting should be advertised on the readme. That is a crucial and integral part of any messaging template. Again, not saying that there needs to be a PR for this, but for the sake of users it would be nice to specify this lack of functionality more clearly upfront.

The order seems to be preserved from the array passed,
but they are laid out in opposite direction?
With addition of every message I should prepend to the original array passsed
or append to the original array passed ?
It seems that it starts laying out items from bottom to top.
which means the latest items should be prepended to the list if I am correct?

@kfiroo Is the reverse rendering of items due to invertible scrollview?
Gifted messenger (Earlier version of gifted chat) rendered in order supplied i.e. top to bottom.
Anyways I have reversed the input array and appending order to take care of the problem.

@jayshah123 Yes, GiftedChat uses InvertibleScrollView to render the messages from the bottom to the top, and also to keep the scroll at the bottom.
@dcurletti You are right, I'll make sure to add that to the readme

I seem to get the same issue but only on Android. The message ordering on iOS works fine.

same here. Inverted on android. Not sure about iOS yet.

And why don't you order the list at Firebase? E.g.
Firebase.database().ref(`chats/${id}`).orderByKey().limitToLast(20);
Firebase id's are based off of the Unix epoch so this way you'll pull the array in the correct order.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iamdurui picture iamdurui  路  3Comments

arayaryoma picture arayaryoma  路  3Comments

Fr33maan picture Fr33maan  路  3Comments

maharjanaman picture maharjanaman  路  3Comments

luisar picture luisar  路  3Comments