【问题标题】:Why are chat messages from firestore showing up in "groups"?为什么来自 Firestore 的聊天消息会显示在“群组”中?
【发布时间】:2021-04-29 22:37:54
【问题描述】:

我正在尝试使用 react-native-gifted-chat 在我的应用中构建聊天室。

不幸的是,聊天出现在“群组”中,而不是按顺序出现。例如,

  1. 我发消息
  2. 别人发消息
  3. 我再发一条消息
  4. 我发送的消息组合在一起,有时出现在其他消息上方,有时出现在下方

这是问题的图片:

请注意一些较新的消息在一些较旧的消息之上,并按发送它的用户分组!

这就是我将消息写入数据库的方式:

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>
            
        )
        
    }
}

我如何阅读这些消息:

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
            });
        })
    }

在 Firestore 中,这是将时间写入数据库的方式:

知道为什么这些消息会组合在一起吗?

这似乎是一个从按创建日期排序的 firestore 中提取消息的简单案例,但这看起来并不正常。

我在天才聊天中发送消息时也收到以下错误,这可能与此有关吗?

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

[有些消息是从美国东海岸发出的,有些是从美国西海岸发出的。我想知道这是否与分组有关?]

【问题讨论】:

    标签: javascript react-native google-cloud-firestore react-native-gifted-chat


    【解决方案1】:

    根据图像,createdAt 字段不是时间戳字段,而是String

    如提到的那样添加时间戳字段here

    createdAt: new Date();
    
    or specific date-time
    
    createdAt: firestore.Timestamp.fromDate(new Date());
    
    or else for server time
    
    createdAt: firestore.FieldValue.serverTimestamp()
    

    如果您能够更正该字段,您的orderBy 查询将以正确的顺序检索数据。

    现在排序发生在 String 字段上,所以它不会按预期工作!

    【讨论】:

    • 是的,但这会将时间显示为“无效日期”,即使有真正的时间戳,它也会错误地排序!也许我可以在从 Firestore 读取数据后将此转换为时间戳?
    • 如果您在阅读后进行转换,则必须手动订购; bcz 按字符串字段排序的检索数据,简单来说,它的顺序不正确;所以,最好把数据保存为时间戳!
    • 同意,我现在保存为时间戳,并尝试在读取后将日期转换为字符串格式
    • 尝试在我的 firebase 读取中转换时间戳(上面的代码),但它不起作用。知道如何在阅读时在 for each 中转换它吗?
    • 酷!因此,将该字段另存为timeStamp -> 使用orderby 查询 -> 如果需要,在处理时对任何字段进行转换
    猜你喜欢
    • 1970-01-01
    • 2019-02-26
    • 1970-01-01
    • 2020-03-14
    • 2017-06-01
    • 2019-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多