首页 > 解决方案 > 为什么我的 firebase 聊天仅在我退出屏幕或关闭聊天并重新打开时才显示消息?

问题描述

聊天应该是即时的,其中消息在输入并存储在 Firebase Firestore 时填充 div。然而,我注意到一件奇怪的事情。仅当我在 Chrome 中更改标签或完全关闭聊天然后重新打开时,聊天才会显示新消息。否则,如果我留在同一个选项卡上查看聊天并等待新消息显示,它不会显示。真的很奇怪。

JSX:

<div className="form-popup" id="myForm">
                    <form className="form-container" onSubmit={this.chatFormSubmit}>

                        <h1>Chat</h1>

                        <label htmlFor="msg"><b>Message</b></label>


                        <div className="chatArea" id='messages'>
                            
                            {this.state.messages.map((message, index) => {
                             return <p key={index}>{message.body.content}</p>
                            })}

                        <div style={{ float:"left", clear: "both" }}
                               ref={(el) => { this.myRef = el; }}>
                            </div>

                        </div>

                       <textarea className="chatInput" ref={this.chatArea} ></textarea>

                        <br />
                        <br />

                        {this.state.writeError ? <p>{this.state.writeError}</p> : null}

                        <button type="submit" className="btn">Send</button>
                        <button type="button" className="btn cancel" onClick={() => this.closeForm()}>Close</button>

                    </form>
                </div>

反应:

这是打开 Chat 并启动 onSnapshot 函数以监听 Firestore 中的变化的函数:

startChatWithProjectManager(doc) {

            
        document.getElementById("myForm").style.display = "block";

        this.setState({docId: doc.id})

        const query = firebase.firestore()
                            .collection('Clients')
                            .doc(this.state.displayName)
                            .collection('Orders')
                            .doc(doc.id)
                            .collection('Messages')
                            .where("uid", "==", this.state.uid)
                            .orderBy('timestamp', 'desc')
                            .limit(12);              
         
            // Start listening to the query.

         this.unsubFromMessages = query.onSnapshot((snapshot) => {
            snapshot.docChanges().forEach((change) => {
            if (change.type === 'removed') { 
      
                console.log(change.id)

            } else {                
            
              this.setState(state => {
                const messages = [...state.messages, {id: change.doc.id, body: change.doc.data()}]
                return {
                    messages
                }
            }, this.scrollToBottom() ) 
            
                        
            }
            
            });
            });      
   
        
}

这是在 Firestore 中存储新消息的函数:

chatFormSubmit(e) {

        e.preventDefault();

  this.setState({ writeError: null });

    
   firebase.firestore()
    .collection('Clients')
    .doc(this.state.displayName)
    .collection('Orders')
    .doc(this.state.docId)
    .collection('Messages')
    .doc()    
    .set({
      content: this.chatArea.current.value,
      timestamp: moment().format('MMMM Do YYYY, h:mm:ss a'),
      uid: this.state.uid,
      name: this.state.displayName,
      email: this.state.email
    })
    .catch((error) => {
    this.setState({ writeError: error.message });
  })
    .then(this.chatArea.current.value = '')   
    
    }

出于某种原因,消息出现在 ChatArea div 中的速度非常缓慢,并且延迟很奇怪,这与我从 Web 中遵循的示例几乎立即弹出消息不同。我不知道发生了什么。

标签: reactjsfirebasegoogle-cloud-firestorejsx

解决方案


我想到了。聊天没有按预期更新的原因是我拥有的 setInterval 函数之一同时连续运行,从而降低了我的应用程序的速度。那里的任何人都对为什么他们的代码在一切看起来都正确时无法工作感到困惑,请始终检查是否有任何其他函数导致无限循环或其他问题。无限循环会干扰网络请求。


推荐阅读