React-native-gifted-chat With Cloud Firestore Pagination
I'm using Firestore to store messages. In order to optimize the mobile application performances, I would like to set a limit(50) in the firestore query. It works well and implement
Solution 1:
Your query is OK for the first time, for consequent queries you must use the ::startAt or ::startAfter methods.
You can find more information in the official documentation. https://firebase.google.com/docs/firestore/query-data/query-cursors
Solution 2:
I am using FlatList in react-native to render chats and I had to paginate the chats list. Since Firestore query cursor is not supported in live listener, I created two list, recentChats
& oldChats
.
I populate recentChats
using live listener query.onSnapshot
& oldChats
using cursor startAfter
. FlatList data is combination of both list and I take care of merging logic.
constMESSAGE_LIMIT = 15;
constChatWindow = props => {
const { sessionId, postMessage, onSendTemplateButtonPress } = props;
// Firestore cursor is not supported in query.onSnapshot so maintaining two chat list// oldChats -> chat list via cursor, recentChats -> chat list via live listenerconst [oldChats, setOldChats] = useState([]);
const [recentChats, setRecentChats] = useState([]);
// if true, show a loader at the top of chat listconst [moreChatsAvailable, setMoreChatsAvailable] = useState(true);
const [inputMessage, setInputMessage] = useState('');
useEffect(() => {
const query = getGuestChatMessagesQuery(sessionId)
.limit(MESSAGE_LIMIT);
const listener = query.onSnapshot(querySnapshot => {
let chats = [];
querySnapshot.forEach(snapshot => {
chats.push(snapshot.data());
});
// merge recentChats & chatsif (recentChats.length > 0) {
const newRecentChats = [];
for (let i = 0; i < chats.length; i++) {
if (chats[i].sessionId === recentChats[0].sessionId) {
break;
}
newRecentChats.push(chats[i]);
}
setRecentChats([...newRecentChats, ...recentChats]);
} else {
setRecentChats(chats);
if (chats.length < MESSAGE_LIMIT) {
setMoreChatsAvailable(false);
}
}
});
return() => {
// unsubscribe listenerlistener();
};
}, []);
constonMessageInputChange = text => {
setInputMessage(text);
};
constonMessageSubmit = () => {
postMessage(inputMessage);
setInputMessage('');
};
constrenderFlatListItem = ({ item }) => {
return (<ChatBubblechat={item} />);
};
constonChatListEndReached = () => {
if (!moreChatsAvailable) {
return;
}
let startAfterTime;
if (oldChats.length > 0) {
startAfterTime = oldChats[oldChats.length - 1].time;
} elseif (recentChats.length > 0) {
startAfterTime = recentChats[recentChats.length - 1].time;
} else {
setMoreChatsAvailable(false);
return;
}
// query data using cursorgetGuestChatMessagesQuery(sessionId)
.startAfter(startAfterTime)
.limit(MESSAGE_LIMIT)
.get()
.then(querySnapshot => {
let chats = [];
querySnapshot.forEach(snapshot => {
chats.push(snapshot.data());
});
if (chats.length === 0) {
setMoreChatsAvailable(false);
} else {
setOldChats([...oldChats, ...chats]);
}
});
};
return (
<Viewstyle={[GenericStyles.fill,GenericStyles.p16]}><FlatListinverteddata={[...recentChats,...oldChats]}
renderItem={renderFlatListItem}keyExtractor={item => item.messageId}
onEndReached={onChatListEndReached}
onEndReachedThreshold={0.2}
ListFooterComponent={moreChatsAvailable ? <ActivityIndicator /> : null}
/>
{
Singleton.isStaff ?
null:
<ChatInputonMessageInputChange={onMessageInputChange}onMessageSubmit={onMessageSubmit}inputMessage={inputMessage}style={GenericStyles.selfEnd}onSendTemplateButtonPress={onSendTemplateButtonPress}
/>
}
</View>
);
};
Post a Comment for "React-native-gifted-chat With Cloud Firestore Pagination"