【问题标题】:React Native Firebase Chat app - Add Listener for new incoming messagesReact Native Firebase 聊天应用程序 - 为新传入消息添加侦听器
【发布时间】:2021-02-17 15:28:37
【问题描述】:

我正在我的应用程序中创建一个利用 Firebase 的聊天功能。我已经阅读了有关添加事件侦听器的文档,但我似乎无法让侦听器更新状态(我相信当状态更新时,应用程序会重新呈现并且应该有新的传入消息)

用例: 您正在与某人聊天,并且您已打开消息/聊天屏幕,并且不想刷新页面以查看新消息...它们应该在消息发布到数据库时显示

 componentDidMount() {
        this.setState({ isLoading: true })
        this.pullMessages()
        this.listener()
        this.setState({ isLoading: false })
   pullMessages = () => {
        let messagesArray = []
        if (this.state.chatroomDetails.users.length === 2) {
            firebase.firestore().collection('chatrooms').doc('private').collection(this.state.chatroomDetails.key).doc('messages').collection('messages').get().then((querySnapshot) => {
                if (!querySnapshot.empty) {
                    querySnapshot.forEach((doc) => {
                        messagesArray.push(doc.data())
                        this.setState({ messages: messagesArray })
                    })
                }
            })


        }
        else {
            firebase.firestore().collection('chatrooms').doc('group').collection(this.state.chatroomDetails.key).doc('messages').collection('messages').get().then((querySnapshot) => {
                if (!querySnapshot.empty) {
                    querySnapshot.forEach((doc) => {
                        messagesArray.push(doc.data())
                        // console.log(messagesArray)
                        this.setState({ messages: messagesArray })
                    })
                } else {
                    console.log('Nothing to Grab')
                }
            })
        }
    }
 listener = () => {
        let messagesArray = []
        if (this.state.chatroomDetails.users.length === 2) {
            firebase.firestore().collection('chatrooms').doc('private').collection(this.state.chatroomDetails.key).doc('messages').collection('messages')
                .onSnapshot(function (querySnapshot) {
                    if (!querySnapshot.empty) {
                        querySnapshot.forEach(function (doc) {
                            console.log('the console');
                            console.log(doc.data());
                            messagesArray.push(doc.data())
                        })
                    }
                })
            this.setState({ messages: messagesArray })
        }
    }

在 listener() 中,我可以看到来自其他设备的新消息,但我似乎无法从这里将其设置为我的状态...帮助!

【问题讨论】:

    标签: reactjs firebase react-native chat addeventlistener


    【解决方案1】:

    状态可能不会更新,因为您正在对其进行变异。当这条线运行时:

    messagesArray.push(doc.data())
    this.setState({ messages: messagesArray })
    

    您正在向消息数组中添加一个已经处于状态的项目,然后将状态设置为不会重新呈现您的组件的相同值。

    您可以通过在每次收到集合更新时将消息值设置为新数组来纠正此问题。像这样:

    this.setState({ messages: [...messagesArray, doc.data()] })
    

    编辑:

    我还注意到您的状态更新不在此处的快照侦听器中:

                    .onSnapshot((querySnapshot) => {
                        if (!querySnapshot.empty) {
                            querySnapshot.forEach((doc) => {
                                console.log('the console');
                                console.log(doc.data());
                                messagesArray.push(doc.data())
                            })
                        }
                    })
                this.setState({ messages: messagesArray })
    

    它应该看起来像这样:

                    .onSnapshot((querySnapshot) => {
                        if (!querySnapshot.empty) {
                            querySnapshot.forEach((doc) => {
                                this.setState({ messages: [...messagesArray, doc.data() })
                            })
                        }
                    })
                
    

    甚至更好地防止不必要地更新状态:

                    .onSnapshot((querySnapshot) => {
                        if (!querySnapshot.empty) {
                            const newMessages = querySnapshot.map((doc) => doc.data())
    
                            this.setState({ messages: [...messagesArray, ...newMessages })
                        }
                    })
                
    

    【讨论】:

    • 您的解决方案看起来很有前途,但我不断收到“无法读取未定义的属性 'setState' :/
    • 这是 react 中的一个绑定问题。尝试将function(querySnapshot) {...} 更改为() => {...}
    • 我已经提取了你的代码并且它的工作,我必须摆脱我的'pullMessages()'函数,因为我相信他们现在正在做同样的事情?我现在遇到了一个问题,它不断重新添加整个状态(所以重复消息),新消息添加到底部:/
    • 是的,这两个函数会做同样的事情。重复的消息很容易修复。只需将messages: [...messageArray, ...newMessages] 更改为messages: newMessages
    猜你喜欢
    • 2020-01-21
    • 2021-10-07
    • 1970-01-01
    • 2019-01-19
    • 1970-01-01
    • 2019-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多