我想显示用户关注的帖子:
- 首先,我查询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>
)}
如果没有,我渲染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
中,但其余字段尚未添加。
我能想到的唯一解决办法是:
设置查询快照外的状态,但当我尝试时,帖子不显示,因为
followingPosts.length
为0,状态不在querySnapshot
外更新弄清楚如何卸载组件,似乎组件没有卸载,所以监听器一直在监听,这就是导致崩溃的原因
-关于这个的说明。我有一个globalPosts
feed,其中一切工作100%,然后在我的"后续"尝试几乎相同的实现时;Feed,当用户发布新帖子
- 改变我创建帖子的方式,我宁愿不这样做
编辑:我现在进入兔子洞,为什么组件安装& &;因此,侦听组件何时应该卸载。这可能就是我撞车的原因!
您的代码有点偏离,因为您为当前用户关注的每个用户创建一个侦听器,并为他们帖子中的每个更改创建侦听器。这将影响性能,并使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(),
],
});
}
});
});