javascript - 优化聊天应用中的 Firestore 实时更新
问题描述
我正在使用 Firestore 实时更新在我的 React Native 应用程序中创建实时聊天。我读到这可能不是建立聊天的最佳方式,但我决定这样做是因为我已经在使用 Firebase 并且聊天不是应用程序的主要目的。那么,在实时聊天的情况下,我将如何优化 Firestore 连接?它通常效果很好,但到目前为止我遇到了一些问题:</p>
- 消息慢慢传来
- 消息发送后不显示
- 推送通知在消息之前到达
这些问题通常发生在互联网连接不佳时(尽管 Whatsapp 消息仍然可以正常工作),但有时也会在连接良好的情况下发生……</p>
这是我查询数据的方式(在 中添加实时侦听器,在 中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
提供的回调。我希望我有所帮助。
推荐阅读
- git - 通过 gitHubDesktop 将文件推送到 gitgub 时出错
- android - 如何在arcore android中用线条渲染文本?
- react-native - 为什么我的 PermissionsAndroid 请求总是返回已授予?
- laravel - 从数组中获取数据
- html - 如何将自定义 url 共享到 vue 中的社交媒体按钮中?
- javascript - 为什么需要多个 rotate() 将每个数字放在正确的位置?- 帆布时钟编号
- makefile - make命令如何不先搜索同一目录下的Makefile?
- arrays - 为什么vs2019在函数执行结束时仍然提示:运行时检查失败# - 变量'binR'周围的堆栈已损坏
- c# - xUnit 的自定义集合属性
- javascript - 如何从 vue 应用程序中的 main.js 文件访问存储 getter 更新值?