Firestore数据不显示在我的平面列表中?



我想显示用户关注的帖子:

  1. 首先,我查询firestore并获得所有用户的列表当前用户正在关注
  2. 对于"关注"中的每个用户,我获得他们的帖子
  3. 我命令他们的数据创建的帖子,使用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>
)}

如果没有,我渲染flatlist:

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);
});

Since querySnapshot in "Following"总是在听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中,但其余字段尚未添加。

我能想到的唯一解决办法是:

  1. 设置查询快照外的状态,但当我尝试时,帖子不显示,因为followingPosts.length为0,状态不在querySnapshot外更新

  2. 弄清楚如何卸载组件,似乎组件没有卸载,所以监听器一直在监听,这就是导致崩溃的原因

-关于这个的说明。我有一个globalPostsfeed,其中一切工作100%,然后在我的"后续"尝试几乎相同的实现时;Feed,当用户发布新帖子

时,应用程序崩溃
  1. 改变我创建帖子的方式,我宁愿不这样做

编辑:我现在进入兔子洞,为什么组件安装& &;因此,侦听组件何时应该卸载。这可能就是我撞车的原因!

您的代码有点偏离,因为您为当前用户关注的每个用户创建一个侦听器,并为他们帖子中的每个更改创建侦听器。这将影响性能,并使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(),
],
});
}
});
});

最新更新