Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Firebase Real Time DB和ReactNative聊天中使用新消息?_Firebase_React Native_Firebase Realtime Database_Chat - Fatal编程技术网

如何在Firebase Real Time DB和ReactNative聊天中使用新消息?

如何在Firebase Real Time DB和ReactNative聊天中使用新消息?,firebase,react-native,firebase-realtime-database,chat,Firebase,React Native,Firebase Realtime Database,Chat,我正在构建一个包含聊天的ReactNative应用程序,我用来保存数据的数据库是来自Firebase的实时数据库 当我导航到聊天屏幕时,首先我会加载一次已经存在的聊天信息: const [messages, setMessages] = useState(); ... let chatRef = firebase.database().ref('chats/' + chatId); let chatData = null; useEffect(() => {

我正在构建一个包含聊天的ReactNative应用程序,我用来保存数据的数据库是来自Firebase的实时数据库

当我导航到聊天屏幕时,首先我会加载一次已经存在的聊天信息:

  const [messages, setMessages] = useState();
  ...

  let chatRef = firebase.database().ref('chats/' + chatId);
  let chatData = null;

  useEffect(() => {
    chatRef.once('value').then((snapshot) => {
      if (snapshot.exists()) {
        ...

        chatData = snapshot.val();
        setMessages(chatData.messages.reverse());

        ...
      } else {
        console.log("No data available");
      }
    }).catch((error) => {
      console.error(error);
    });
  },[]);
我对引用使用了.once方法,但仍然必须使用useEffect来避免无限循环,因为我将聊天信息设置为状态,是什么触发屏幕再次打印,否则将再次调用.once方法

但是,当我希望到达数据库的新消息在已经打开的聊天屏幕上实时显示时,我的问题就来了。为此,我尝试了以下几点:

let messagesRef = chatRef.child('messages');

messagesRef.limitToLast(1).on('child_added', (snapshot) => {
  let data = snapshot.val();
  if(snapshot.key > chatLen){
    console.log("NEW MESSAGE IN THIS CHAT: "+data.text);
    let auxMessages = messages;
    auxMessages[-1] = data;
    setMessages(auxMessages)
  }else{
    console.log("REPEATED NOTIFICATION OF MESSAGE: "+data.text);
  }
});
snapshot.key我刚刚收到事件的消息编号,以及chatLen屏幕上已经显示的聊天长度

使用最后一段代码,我尝试创建新消息,如果我收到消息的重复事件,我只会忽略它(但我想知道为什么会发生这种情况),但如果是新消息,我想更新屏幕上显示的内容,因此我将其添加到状态中的消息中,但随后我进入了一个infinte循环,我不知道如何打破它,因为我不知道如何在屏幕订阅新消息的方式中加入另一个useffect子句,但它不会每次打印屏幕时都这样做,但同时,每次新事件到达时,它都由最后一个“if”子句中的代码处理


对不起,对于我的英语,任何建议都将不胜感激,这是我第一次使用firebase实时数据库引用,我可能在做或理解某些错误。

我建议使用实时侦听器,并限制要访问
ref
的元素。这样,您应该始终只获得最后20个元素,例如:


const[messages,setMessages]=useState();
让chatRef=firebase
.数据库()
.ref(“chats/”+chatId)
.limitToLast(20);
让chatData=null;
useffect(()=>{
chatRef.on(“添加的子项”,(数据)=>{
setMessages({…messages,[data.key]:data.val()});
});
chatRef.on(“子项更改”,(数据)=>{
setMessages({…messages,[data.key]:data.val()});
});
chatRef.on(“已删除子项”,(数据)=>{
const{[data.key]:已删除,…rest}=消息;
设置消息(rest);
});
//离开react组件时关闭侦听器
return()=>chatRef.off();
}, []);
对象。条目(消息)
.sort(([a],[b])=>{
//按键字符串值对对象元素排序
返回(“+a.attr).localeCompare(b.attr);
})
.map((e)=>{
常数[key,val]=e;
//键入消息数据库密钥
//验证您的消息值
});
您还可以将数据直接存储到数组中,并通过搜索相应的
键来添加、更新和删除元素


离开组件时,请确保关闭侦听器。

谢谢你,塔里克,我将尝试两种方法,一种是限制,另一种是“关闭”侦听器,我认为这可能是解决方案。我保证公布结果。