javascript - 优化聊天应用中的 Firestore 实时更新

标签 javascript firebase react-native google-cloud-firestore react-native-firebase

我正在使用 Firestore 实时更新在我的 React Native 应用中创建实时聊天。我读到这可能不是建立聊天的最佳方式,但我决定这样做是因为我已经在使用 Firebase 并且聊天不是该应用程序的主要目的。那么,在实时聊天的情况下,我将如何优化 Firestore 连接?它通常工作得很好,但到目前为止我遇到了一些问题:

  • 消息进来很慢
  • 消息发送后没有显示
  • 推送通知先于消息到达

这些问题通常发生在互联网连接不佳时(尽管 Whatsapp 消息仍然可以正常工作),但有时也会在良好的连接下发生......

下面是我查询数据的方式(实时监听器在componentDidMount中添加,在componenWillUnmount中移除):

onLogUpdate = (querySnapshot) => {
  allMessages = this.state.allMessages

  cb = (allMsgs) => {
    allMsgs.sort((a,b) => {
      a = new Date(a.timestamp);
      b = new Date(b.timestamp);
      return a>b ? -1 : a<b ? 1 : 0;
    })
    messages = _.takeRight(allMsgs, this.state.messageLimit)
    this.setState({ loading: false, messages, allMessages: allMsgs })
  }

  async.map(querySnapshot._changes, (change, done) => {
    if (change.type === "added") {
      const msgData = change._document.data()
        if (msgData.origin == 'user') {
          this.usersRef.doc(msgData.byWhom).get()
            .then(usr => {
              msgData.user = usr.data()
              done(null, msgData)
            })
            .catch(err => { console.log('error getting user in log:', err) })
        } else {
          done(null, msgData)
        }
    } else {
      done(null, 0)
    }
  }, (err, results) => {
    const res = results.filter(el => { return el != 0 })
    allMessages = _.concat(allMessages, res)
    cb(allMessages)
  })
}

这就是我添加新消息的方式:

// in utils.js
exports.addLogMessage = (msgObj, moment_id, callback) => {
  logMessagesRef.add(msgObj)
    .then(ref => {
      momentsRef.doc(moment_id).get()
        .then(doc => {
          const logMsgs = doc.data().logMessages ? doc.data().logMessages : []
          logMsgs.push(ref.id)
          momentsRef.doc(moment_id).update({ logMessages: logMsgs })
        })
        .then(() => {
          if (callback) {
            callback()
          }
        })
    })
    .catch(err => { console.log('error sending logMessage:', err) })
}

// in chat Screen
sendLogMessage = () => {
  if (this.state.newMessage.length > 0) {
    firebase.analytics().logEvent('send_log_message')
    this.setState({ newMessage: '' })
    const msgObj = {
      text: this.state.newMessage,
      origin: 'user',
      timestamp: Date.now(),
      byWhom: this.state.user._id,
      toWhichMoment: this.state.moment._id
    }
    addLogMessage(msgObj, this.state.moment._id)
  }
}

任何建议将不胜感激:)

最佳答案

我正在做类似的事情,但在我提交数据后,它不会显示在 ListView 中。我通过将新条目推送到正在映射的预先存在的状态来解决它,并且由于 setState() 调用了 render() 方法,它工作得很好。我做了这样的事情:

 sendLogMessage().then(newData => {
     joined = this.state.data.concat(newData);
     this.setState({ data: joined})
 })

这当然是假设您正在使用 this.state.data.map 来呈现聊天记录。当我无法看到我发送的消息时,这将起作用,至于随着数据库更新而更新的消息,您可能想使用 Firebase API 提供的 .onDataChange 回调。 .我希望我有所帮助。

关于javascript - 优化聊天应用中的 Firestore 实时更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52611857/

相关文章:

javascript - Console.log 在 if 语句中触发,但其余代码不会

ios - FirebaseUI-iOS FUIIndexArray 用法

javascript - 使用 d3 域调用更改 dc 直方图的存储桶

javascript - chart.js 饼图问题显示 : none

android - 如何从一个 userID Firebase Android 中检索数据

reactjs - 无法使用react-native-snap-carousel

ios - iOS 上 React Native 中的 BatchedBridge 错误

react-native - Metro bundler 不会随着 expo start 自动启动

javascript - 在后面的链链接中使用第一个 promise 的值(value)

c++ - ios firebase::App::Create 上的 firebase C++ sdk 返回 nullptr