Javascript 在多频道聊天应用程序中,如何仅显示与特定聊天频道相关的消息?
环境:expo 36.0.0/React Native 0.61/React Native gifted chat 0.13.0/firebase 7.6.0 我的目标:仅在Gifted chat UI上呈现特定于特定聊天频道的消息 预期结果:只有与给定频道相关的消息才会显示在Gifted Chat UI上 实际结果:Javascript 在多频道聊天应用程序中,如何仅显示与特定聊天频道相关的消息?,javascript,react-native,firebase-realtime-database,react-native-firebase,react-native-gifted-chat,Javascript,React Native,Firebase Realtime Database,React Native Firebase,React Native Gifted Chat,环境:expo 36.0.0/React Native 0.61/React Native gifted chat 0.13.0/firebase 7.6.0 我的目标:仅在Gifted chat UI上呈现特定于特定聊天频道的消息 预期结果:只有与给定频道相关的消息才会显示在Gifted Chat UI上 实际结果: 当我从一个聊天频道导航到另一个聊天频道时,总的消息会累积起来 当我回到以前的频道时,同一聊天频道的消息会重复多次 警告:遇到两个具有相同密钥的子项,%s。键应该是唯一的,以便组件
%s
。键应该是唯一的,以便组件在更新期间保持其标识。非唯一键可能会导致复制和/或忽略子项-不支持该行为,并且可能在将来的版本中更改。%s async componentDidMount() {
await this.getSessionInfo();
await this.getCurrentProfile();
await this.getMessages();
};
async componentDidUpdate(prevProps) {
/* sessionID represent a chat channel and corresponding node in Firebase */
/* If user navigates from one channel to another we establish a connection with new node and get the
corresponding messages */
if (this.props.navigation.state.params.sessionID !== prevProps.navigation.state.params.sessionID) {
await this.getSessionInfo();
await this.getCurrentProfile();
/* Subscribe to new chat channel */
await this.ref();
await this.getMessages();
}
};
async componentWillUnmount() {
/* Unsubscribe from database */
await this.off();
}
/* Get messages to display after component is mounted on screen */
getMessages = () => {
this.connect(message => {
this.setState(previousState => ({
messages: GiftedChat.append(previousState.messages, message),
}))
});
}
/* Each sessionID corresponds to a chat channel and node in Firebase */
ref = () => {
return database.ref(`/sessions/${this.state.sessionID}`);
}
/* Fetch last 20 messages pertaining to given chat channel and lister to parse new incoming message */
connect = (callback) => {
this.ref()
.limitToLast(20)
.on('child_added', snapshot => callback(this.parse(snapshot)));
}
/* newly created message object in GiftedChat format */
parse = snapshot => {
const { timestamp: numberStamp, text, user } = snapshot.val();
const { key: _id } = snapshot;
const timestamp = new Date(numberStamp);
const message = {
_id,
timestamp,
text,
user,
};
return message;
};
/* function that accepts an array of messages then loop through messages */
send = (messages) => {
for (let i = 0; i < messages.length; i++) {
const { text, user } = messages[i];
const message = {
text,
user
};
this.append(message);
}
};
/* append function will save the message object with a unique ID */
append = message => this.ref().push(message);
异步组件didmount(){
等待此消息。getSessionInfo();
等待此消息。getCurrentProfile();
等待此消息。getMessages();
};
异步组件更新(prevProps){
/*sessionID表示Firebase中的聊天频道和相应节点*/
/*如果用户从一个通道导航到另一个通道,我们将与新节点建立连接并获取
相应的消息*/
if(this.props.navigation.state.params.sessionID!==prevProps.navigation.state.params.sessionID){
等待此消息。getSessionInfo();
等待此消息。getCurrentProfile();
/*订阅新的聊天频道*/
等待这个;
等待此消息。getMessages();
}
};
异步组件willunmount(){
/*取消订阅数据库*/
等待这个。关();
}
/*在屏幕上安装组件后获取要显示的消息*/
getMessages=()=>{
此.connect(消息=>{
this.setState(previousState=>({
消息:giftechat.append(previousState.messages,message),
}))
});
}
/*每个sessionID对应于Firebase中的聊天频道和节点*/
ref=()=>{
返回database.ref(`/sessions/${this.state.sessionID}`);
}
/*获取与给定聊天频道和列表器相关的最后20条消息,以解析新的传入消息*/
连接=(回调)=>{
this.ref()
.limitToLast(20)
.on('child_added',snapshot=>callback(this.parse(snapshot));
}
/*新创建的GifteChat格式的消息对象*/
解析=快照=>{
const{timestamp:numberStamp,text,user}=snapshot.val();
const{key:_id}=快照;
const timestamp=新日期(numberStamp);
常量消息={
_身份证,
时间戳,
文本,
用户,
};
返回消息;
};
/*函数,该函数接受消息数组,然后在消息中循环*/
发送=(消息)=>{
for(设i=0;i根据Brett Gregson的建议和Mike Kamerman的回答,我实现了以下解决方案
尝试使用类似于Mike Kamermans在此处的回答的链接将状态设置为emtpy数组非常感谢Brett花时间回答我的问题,以及Ivan和Frank编辑我的问题并使其更易于理解。Mike Kamerman答案中的概念解释帮助我实现了选项1的一个版本,该版本在他的答案中有所体现。很高兴你找到了答案
async componentDidUpdate(prevProps) {
if (this.props.navigation.state.params.sessionID !== prevProps.navigation.state.params.sessionID) {
await this.getSessionInfo();
await this.ref();
await this.switchSession();
}
};
switchSession = async () => {
await this.setState({ messages: [] });
await this.getMessages();
}