0

I am trying to use react-native-gifted-chat to build a chat room in my app.

Unfortunately, the chat's are appearing in "groups", not sequentially. For example,

  1. I send a message
  2. Someone else sends a message
  3. I send another message
  4. The messages I send group together, sometimes appearing above other messages, sometimes below

Here is an image of the issue:

enter image description here

Notice how some younger messages are above some older messages, and grouped by the user who sent it!

This is how I write the message to the DB:

onSend = async(message) => {
        this.setState({isTyping: true})
        await Firebase.firestore().collection("chat")
        .add({
            user: {
                _id: this.state.currentUser.id,
                name: this.state.currentUser.name,
                avatar: this.state.currentUser.avatar,
            },
            
        })
        .then(ref => this.setState({messageID: ref.id}))

        await Firebase.firestore().collection("chat")
        .doc(this.state.messageID)
        .set({
            _id: this.state.messageID,
            text: message[0].text,
            createdAt: dayjs(Moment(message[0].createdAt).format('LLL')).locale('en-ca').format()
        }, { merge: true })

    }

    render() { 
        return (
            <View style={{backgroundColor: '#000000', flex: 1}}>
                <GiftedChat
                    showUserAvatar={true}
                    isTyping={this.state.isTyping}
                    renderUsernameOnMessage={true}
                    messages={this.state.messages}
                    onSend={message => this.onSend(message)}
                    scrollToBottom
                    locale = { dayjs.locale('en-ca') }
                    showAvatarForEveryMessage = {true}
                    dateFormat = 'll'
                    timeFormat = 'LT'
                    onPressAvatar={user => this.getProfile(user)}
                />
            </View>
            
        )
        
    }
}

How I read the messages:

getCurrentMessages = async() => {

        await Firebase.firestore().collection("chat")
        .orderBy("createdAt", "desc")
        .limit(50)
        .onSnapshot(querySnapshot => {
            const messages = []

            querySnapshot.forEach((res) => {
                const { 
                    _id,
                    user,
                    text,
                    createdAt,
                    } = res.data();
    
                    messages.push({
                        key: res._id,
                        _id,
                        user,
                        text,
                        createdAt,
                    });
            })

            this.setState({
                messages,
                isLoading: false, 
                isTyping: false
            });
        })
    }

In firestore, this is how the time is written to the db:

enter image description here

Any idea why the messages are getting grouped together?

It seems like a simple case of pulling the messages from firestore ordered by date created, but that doesn't look like its working correctly.

I also get the following error when I send a message in gifted chat, could this have something to do with it?

react-native-gifted-chat] GiftedChat: `user` is missing for message {"_id":"lxYBMTV0sD7kaLQOsQLp","text":"Test 5","createdAt":"2021-01-25T22:05:00-08:00"}

[Some of the messages were sent from the east coast, some from the west coast of the USA. I wonder if this has something to do with the groupings?]

kalculated
  • 299
  • 4
  • 19

1 Answers1

1

As per the image it seems, the createdAt field is not a timestamp field, it's a String.

To add a timestamp field as mentioned here

createdAt: new Date();

or specific date-time

createdAt: firestore.Timestamp.fromDate(new Date());

or else for server time

createdAt: firestore.FieldValue.serverTimestamp()

enter image description here

If you are able to get the field corrected, your orderBy query would retrieve the data in correct order.

Now the ordering happens on a String field, so it won't work as expected!

Muthu Thavamani
  • 1,325
  • 9
  • 19
  • Yes, but this displays the time as "invalid date", and still even with a real timestamp, it orders things incorrectly! perhaps I can do this conversion to a timestamp AFTER I read from firestore? – kalculated Jan 26 '21 at 06:16
  • if you do the conversion after read you have to order it manually; bcz the retrieved data ordered by a string field, in simple words, it's in incorrect order; So, it's good to save the data as timestamp! – Muthu Thavamani Jan 26 '21 at 06:18
  • Agreed, I am saving as a timestamp now, and trying to convert the date to the string format after reading – kalculated Jan 26 '21 at 06:20
  • Trying to convert the timestamp in my firebase read (code above) but its not working. Any idea how to convert it within the for each while reading? – kalculated Jan 26 '21 at 06:22
  • Cool! So, save the field as `timeStamp` -> query with `orderby` -> do the conversion if needed on any field while processing – Muthu Thavamani Jan 26 '21 at 06:23
  • for converting timestamp to `String` or `Date` - https://stackoverflow.com/questions/52247445/how-do-i-convert-a-firestore-date-timestamp-to-a-js-date/52247484 – Muthu Thavamani Jan 26 '21 at 06:25
  • Yes, exactly, but when I try to do messages.push({ key: res._id, _id, user, text, Moment(createdAt).format('LLL') }); I get an error – kalculated Jan 26 '21 at 06:25
  • Fixed it! messages.forEach((message) => { message.createdAt = Moment(message.createdAt.toDate()).format('LLL') }) – kalculated Jan 26 '21 at 06:30
  • Nevermind, still doesn't work. The messages are all out of order now again – kalculated Jan 26 '21 at 06:31
  • do you still have old data that has `createdAt` as `String`? – Muthu Thavamani Jan 26 '21 at 06:34
  • Yes, that was the issue, I think everything is fixed now. I have tried chatting between expo on my phone and simulator and everything is working fine now, no invalid date, no grouping messages. Will push this out as an update and hopefully it works globally – kalculated Jan 26 '21 at 06:37