当 firestore 数据库发生变化时,有没有办法更新平面列表?
Is there a way to update a flatlist when there's a change in firestore database?
我有一个显示用户个人资料、姓名和最后发送的消息的列表。几乎在某种程度上,常规消息传递应用程序显示用户。我想要做的是在显示的用户发生变化时更新列表。我尝试让它在渲染时更新,但通过重置状态,它进入无限循环,在几秒钟内将我的读取操作提高到 10k。到目前为止,我已经通过拉动刷新对其进行了更新,但我希望它能够实时更新。我不确定我是否需要使用云函数(例如 onCreate)或计时器来避免快速超过我的配额限制。
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>
);
}
}
我这样做解决了。
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();
});
};
我有一个显示用户个人资料、姓名和最后发送的消息的列表。几乎在某种程度上,常规消息传递应用程序显示用户。我想要做的是在显示的用户发生变化时更新列表。我尝试让它在渲染时更新,但通过重置状态,它进入无限循环,在几秒钟内将我的读取操作提高到 10k。到目前为止,我已经通过拉动刷新对其进行了更新,但我希望它能够实时更新。我不确定我是否需要使用云函数(例如 onCreate)或计时器来避免快速超过我的配额限制。
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>
);
}
}
我这样做解决了。
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();
});
};