javascript - Firestore 数据未显示在我的平面列表中?
问题描述
我正在尝试显示用户关注的任何人的帖子:
- 首先,我查询 firestore 并获取当前用户关注的所有用户的列表
- 对于“关注”中的每个用户,我都会收到他们的帖子
- 我使用 javascript 排序函数按创建的数据排序他们的帖子
这是代码:
constructor() {
super();
this.firestoreRef = Firebase.firestore().collection('following').doc(Firebase.auth().currentUser.uid).collection('following');
this.state = {
isLoading: true,
followingPosts: [],
};
}
componentDidMount() {
this.setState({isLoading: true})
this.unsubscribe = this.firestoreRef.onSnapshot(this.getCollection);
}
componentWillUnmount(){
this.unsubscribe();
}
getCollection = async (querySnapshot) => {
const followingPosts = [];
querySnapshot.forEach(async (res) => {
await Firebase.firestore()
.collection('globalPosts')
.where("uid", "==", res.data().uid)
.onSnapshot(function(query) {
query.forEach((doc) => {
const {
..Fields
} = doc.data();
followingPosts.push({
key: doc.id,
..Fields
});
})
followingPosts.sort(function(a,b){
return b.date_created.toDate() - a.date_created.toDate()
})
});
})
this.setState({
followingPosts,
isLoading: false,
})
}
问题在于设置状态。如果“后续帖子”数组为空,我会渲染:
if (this.state.followingPosts.length == 0) {
return(
<View style={styles.emptyContainer}>
<Text style = {styles.buttonText}>following feed coming soon!</Text>
<TouchableOpacity
style = {styles.button}
onPress={() => this.onShare()} >
<Text style = {styles.buttonText}>invite friends to traderank</Text>
</TouchableOpacity>
</View>
)}
如果没有,我会渲染平面列表:
return (
<View style={styles.view}>
<FlatList
data={this.state.followingPosts}
renderItem={renderItem}
keyExtractor={item => item.key}
contentContainerStyle={{ paddingBottom: 50 }}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
onRefresh={this._refresh}
refreshing={this.state.isLoading}
/>
</View>
)
该数组当前始终为“空”,因为我正在设置状态 OUTSIDE 查询快照。
但是当我把我setState
的移到里面时querySnapshot
:
querySnapshot.forEach(async (res) => {
await Firebase.firestore()
.collection('globalPosts')
.where("uid", "==", res.data().uid)
.onSnapshot(function(query) {
query.forEach((doc) => {
const {
...
} = doc.data();
followingPosts.push({
key: doc.id,
...
});
})
followingPosts.sort(function(a,b) {
return b.date_created.toDate() - a.date_created.toDate()
})
console.log(followingPosts)
this.setState({ <------------- here
followingPosts,
isLoading: false,
})
}.bind(this))
})
console.log(followingPosts)
帖子显示正常,但是当当前用户关注的用户发布帖子时,应用程序崩溃,因为帖子是如何写入 Firestore 的:
(从用户创建帖子的位置):
await Firebase.firestore()
.collection('globalPosts')
.add({
uid: this.state.uid
})
.then((docRef) => this.uploadToStorage(docRef.id))
.catch(function(error) {
console.error("Error storing and retrieving image url: ", error);
});
await Firebase.firestore()
.collection('globalPosts')
.doc(this.state.postID)
.set ({
... More Fields
})
.catch(function(error) {
console.error("Error writing document to global posts: ", error);
});
由于“Following”中的querySnapshot一直在监听firestore,所以我一写帖子,应用程序就崩溃了,因为创建代码的前半部分:
await Firebase.firestore()
.collection('globalPosts')
.add({
uid: this.state.uid <------------------------- only the UID is added initially
})
.then((docRef) => this.uploadToStorage(docRef.id))
.catch(function(error) {
console.error("Error storing and retrieving image url: ", error);
});
帖子已添加到globalPosts
,但尚未添加其余字段。
我能想到的唯一解决方案是:
在查询快照之外设置状态,但是当我尝试这样做时,帖子不会显示,因为
followingPosts.length
它是 0 并且状态不会在外部更新querySnapshot
弄清楚如何卸载组件,似乎组件没有卸载,所以监听器总是在监听,这就是导致崩溃的原因
-关于这个的注释。我有一个globalPosts
提要,一切都 100% 正常工作,然后在我的“关注”提要中尝试几乎相同的实现时,当用户发布新帖子时应用程序崩溃
- 改变我创建帖子的方式,我不想这样做
编辑:我现在正在深入了解为什么要安装组件并因此在应该卸载组件时进行监听。这可能是我崩溃的原因!
解决方案
您的代码有点偏离,因为您为当前用户关注的每个用户创建一个列表器,并在其帖子的每次更改时创建一个列表器。这将影响性能并使 Firestore 的成本增加两倍。对于当前用户感兴趣的帖子,您应该只有一个侦听器。
这个想法是,当组件挂载时,您可以使用正常的 get 方法获取当前用户正在关注的所有用户,而不是列表器,然后将此用户添加到状态中。同时,您应该有一个 globalPosts 的侦听器,它通过过滤帖子所有者的字段来获取帖子。
像这样的东西:
// get users that current user is following
firestore
.collection("users")
.doc(auth.currentUser.uid)
.get().then((doc) => this.setState({following: [...doc.data().following]}))
// set a listner for those users' posts and take advantage of **in** operator
this.unsubscribeFirestore = firestore
.collection("globalPosts")
.where("owner", "in", following)
.onSnapshot((snapshot) => {
snapshot.docChanges().forEach((change) => {
if (change.type === "added") {
this.setState({
followingPosts: [
...this.state.followingPosts,
change.doc.data(),
],
});
}
});
});
推荐阅读
- java - 最大整数值java
- algorithm - 动态规划的加权区间问题
- functional-programming - smlnj - 在 Int 列表中添加偶数和奇数元素的函数
- go - 在 Go gin 中实现 IP 限制
- javascript - 如何为 javascript/react 使用美化?
- html - 如何将加载的数据正确绑定到@ng-select,angular6
- java - 从 Spring Boot 生成的 War 文件未部署到 Weblogic 12c
- r - 如何使用data.frame计算R中股票的每日收益?
- google-maps - 是否仍然可以在 AIR 应用程序 (as3) 中显示 Google 地图?
- r - 在一列中复制具有不同值的行