I have a list that displays user profiles, names, and the last message sent. Pretty much in a way a regular messaging app displays users. What I'm trying to do is have the list update when there's a change from the users being displayed. I tried having it update on render but with resetting states, it goes onto an infinite loop which brought up my read operations to 10k in a matter of seconds. So far I have it update with pull to refresh but I want it to update live. I'm not sure if I would need to use cloud functions (e.g. onCreate) or a timer to not quickly go over my quota limit.
import React, { Component } from "react";
import { View, FlatList } from "react-native";
import { ListItem } from "react-native-elements";
import fireStoreDB from "../database/FirestoreDB";
export default class Home extends Component {
constructor(props) {
super(props);
this.state = {
usersInfo: [],
refreshing: false
};
}
componentDidMount() {
this.LoadUsers();
}
LoadUsers = () => {
fireStoreDB
.getAllUsersExceptCurrent()
.then(
users =>
Promise.all(
users.map(
({ id, username, avatar }) =>
fireStoreDB
.getUserLastMessage(fireStoreDB.getUID, id)
.then(message => ({ id, username, avatar, message }))
)
)
)
.then(users => {
this.setState({
usersInfo: users.filter(x => typeof x.avatar !== "undefined"),
refreshing: false
});
});
};
renderItem = ({ item }) => (
<ListItem
onPress={() => {
this.props.navigation.navigate("Chat", {
userTo: item.id,
UserToUsername: item.username,
LoadUsers: this.LoadUsers
});
}}
title={item.username}
subtitle={item.message}
leftAvatar={{ source: { uri: item.avatar } }}
bottomDivider
chevron
/>
);
render() {
return (
<View>
<FlatList
data={this.state.usersInfo}
renderItem={this.renderItem}
keyExtractor={item => item.id}
refreshing={this.state.refreshing}
onRefresh={() => {
this.setState({ refreshing: true });
this.LoadUsers();
}}
/>
</View>
);
}
}
I solved it by doing this.
async componentDidMount() {
await Font.loadAsync({
"open-sans-semi-bold": require("../assets/fonts/OpenSans-SemiBold.ttf"),
Roboto: require("../node_modules/native-base/Fonts/Roboto.ttf"),
Roboto_medium: require("../node_modules/native-base/Fonts/Roboto_medium.ttf"),
...Ionicons.font
});
this.unsubscribeMsg = fireStoreDB.lastMsgListener(this.LoadUsers);
this.unsubscribeUser = fireStoreDB.userProfileListener(this.LoadUsers);
this.setState({ isReady: true });
}
componentWillUnmount() {
this.unsubscribeUser();
this.unsubscribeMsg();
}
lastMsgListener = loadUsersCallback => {
return firebase
.firestore()
.collectionGroup("chats")
.onSnapshot(() => {
loadUsersCallback();
});
};
userProfileListener = loadUsersCallback => {
return firebase
.firestore()
.collection("users")
.onSnapshot(() => {
loadUsersCallback();
});
};