我正在尝试创建一个聊天应用程序,并且有一个小问题。每当我从firebase加载消息时,它们就会以未排序的顺序出现在聊天应用程序中,因此我想按时间戳对消息进行排序,以便它们按顺序出现。如果我在useEffect的onReceive中移动sort和setMessages,则可以执行此操作,但是我觉得这样效率很低,因为它对从firebase检索到的每个消息都分别设置时间和setMessages。我想在所有消息都加载到数组后最后做所有事情。
现在,有了我的日志,我得到了:
[REDACTED TIME] LOG []
[REDACTED TIME] LOG pushing into loadedMessages
[REDACTED TIME] LOG pushing into loadedMessages
因此,它首先打印(空)数组,然后加载消息。如何确保以正确的顺序完成此操作?
useEffect(() => {
// Gets User ID
fetchUserId(getUserId());
const messagesRef = firebase.database().ref(`${companySymbol}Messages`);
messagesRef.off();
messagesRef.off();
const onReceive = async (data) => {
const message = data.val();
const iMessage = {
_id: message._id,
text: message.text,
createdAt: new Date(message.createdAt),
user: {
_id: message.user._id,
name: message.user.name,
},
};
loadedMessages.push(iMessage);
console.log('pushing into loadedMessages');
};
messagesRef.on('child_added', onReceive);
loadedMessages.sort(
(message1, message2) => message2.createdAt - message1.createdAt,
);
console.log(loadedMessages);
return () => {
console.log('useEffect Return:');
messagesRef.off();
};
}, []);
我认为这种观点有些偏离。正确的方法是获取已排序的Firebase数据。
Firebase具有内置的排序方式,尽管它确实有其局限性。
在我看来,你可以尝试执行以下操作:
const messagesRef = firebase.database().ref(`${companySymbol}Messages`);
messagesRef.orderByChild("createdAt").on("child_added", function(snapshot) {
// the callback function once a new message has been created.
console.log(snapshot.val());
});
而且,如果我还想增加一件事,那么一旦你拥有一千多封邮件,那么从时间的推移中传递每条消息可能会有些麻烦,因此,我建议你限制它。例如,可以使用内置的极限功能来实现limitToLast(1000)
。
祝你好运!