React Native Firebase 聊天应用程序 - 为新传入消息添加监听器

React Native Firebase Chat app - Add Listener for new incoming messages

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

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

 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() 中,我可以看到来自其他设备的新消息,但我似乎无法从这里将其设置为我的状态...求救!

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

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

您正在向已处于该状态的消息数组添加一个项目,然后将状态设置为相同的值,这不会 re-render 您的组件。

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

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