如何在Back4App Parse服务中使用两个useParseQuery钩子实现一对一聊天
解决方案
优先方案:使用复合查询,仅调用一次useParseQuery
你不需要调用两次useParseQuery,Parse本身支持or复合查询,可以直接合并两个查询条件,一次拉取所有收发消息,避免多查询状态同步问题。
import { ActivityIndicator, FlatList, View, Text } from 'react-native'; const App = () => { // 当前登录用户ID,示例为amit,实际可从Parse.User.current()获取 const currentUserId = 'amit'; // 如果是和特定用户的一对一私聊,可补充对方ID,示例对方ID为bob // const targetUserId = 'bob'; // 查询1:当前用户发送的消息 const sendQuery = new Parse.Query('Chat_message'); sendQuery.equalTo('from', currentUserId); // 私聊场景补充条件:sendQuery.equalTo('to', targetUserId); // 查询2:当前用户接收的消息 const receiveQuery = new Parse.Query('Chat_message'); receiveQuery.equalTo('to', currentUserId); // 私聊场景补充条件:receiveQuery.equalTo('from', targetUserId); // 合并两个查询 const combinedQuery = Parse.Query.or(sendQuery, receiveQuery); // 按消息发送时间升序排列,Parse默认自带createdAt字段无需手动创建 combinedQuery.ascending('createdAt'); // 仅调用一次钩子即可拿到所有收发消息 const { isLive, isLoading, isSyncing, results, count, error, reload } = useParseQuery(combinedQuery); if (isLoading) { return <ActivityIndicator />; } return ( <FlatList data={results} renderItem={({ item }) => ( <View style={{ height: 70, flex: 1, // 自己发的消息靠右,收到的消息靠左 alignItems: item.get('from') === currentUserId ? 'flex-end' : 'flex-start', justifyContent: 'center', paddingHorizontal: 16 }}> {/* 注意你定义的字段名为message,原代码多写了s */} <Text>message: {item.get('message')}</Text> </View> )} /> ); };
若确实需要调用两次useParseQuery的实现方式
如果业务场景必须拆分两次查询,可以分别调用两次钩子,等两个查询都加载完成后合并结果再按时间排序:
const App = () => { const currentUserId = 'amit'; const sendQuery = new Parse.Query('Chat_message').equalTo('from', currentUserId).ascending('createdAt'); const receiveQuery = new Parse.Query('Chat_message').equalTo('to', currentUserId).ascending('createdAt'); // 调用两次钩子分别获取结果 const sendRes = useParseQuery(sendQuery); const receiveRes = useParseQuery(receiveQuery); // 任意一个查询加载中都显示加载状态 if (sendRes.isLoading || receiveRes.isLoading) { return <ActivityIndicator />; } // 合并两个结果数组,再按创建时间统一排序 const allMessages = [...sendRes.results, ...receiveRes.results].sort((a, b) => a.createdAt - b.createdAt); return ( <FlatList data={allMessages} // 渲染逻辑和上面一致 /> ) }
优化建议
- 建议给
Chat_message表增加会话ID(roomId)字段,每一对私聊用户生成唯一的roomId,后续按roomId拉取消息的性能远高于每次拼接from/to条件 - 可扩展消息类型、已读状态字段,方便后续功能迭代
- 开启Parse的实时查询功能,无需手动刷新即可接收新消息
内容的提问来源于stack exchange,提问作者bikashamit
相关产品推荐
相关产品推荐

