Reputation: 23
I am building a soical media application using Firebase Firestore and React. I have a "posts" collection which stores post documents. In that post document, I store in a field the user ID of the creator of the post.
I also have a "users" collection which has user documents for authenticated users. In this user document I have a "friendList" array which is a list of user IDs.
I want to query for all posts created by the users in a "friendList" array and also listen for changes in the database.
I can get the querysnapshot for posts form a single user. But, I do not seem to find any solution for my problem.
Below is the code for my component where I need the posts:
export default function HomepageFeed({ friendList }) {
const { currentUser } = useAuth();
const [posts, setPosts] = useState([]);
useEffect(() => {
getPostsFromFriends(friendList);
}, []);
async function getPostsFromFriends(friendList) {
const promises = [];
promises.push(getPosts(currentUser.uid));
for (let i = 0; i < friendList.length; i++) {
promises.push(getPosts(friendList[i]));
}
const postsForHomepageFeed = await Promise.all(promises);
setPosts(postsForHomepageFeed);
}
function getPosts(userId) {
return new Promise((resolve, reject) => {
db.collection('posts')
.orderBy('timestamp', 'desc')
.where('userId', '==', userId)
.onSnapshot((snapshot) => {
const data = snapshot.docs;
if (data) resolve(data);
else
reject({
error: `error getting posts from ${userId}`,
});
});
});
}
...render function here...
<div className='feed_container'>
{friendsPosts.map(({ id, post }) => {
return (<Post
key={id}
id={id}
... /> )}
</div>
Upvotes: 0
Views: 1062
Reputation: 50830
You would have to fetch that friendList
array from user's document and make new requests for fetching posts from those users.
const db = firebase.firestore()
const getUserFriends = async (userId) => {
return (await db.collection("users").doc(userId).get()).data().friendList
}
const getFriendsPosts = async (friendUids) => {
const postsCol = db.collection("posts")
const requests = friendsUids.map(f => postsCol.where("userId", "==", f))
const postsQSnaps = await Promise.all(requests)
let posts = []
postsQSnaps.forEach(qSnap => {
posts = [...posts, ...qSnap.docs.map(p => ({ id: p.id, ...p.data() }))]
})
console.log(posts)
return posts
}
Alternatively, you can in
operator in query but if friendList
array can contain more than 10 users, using Promise.all()
as in the above code snippet might be easier.
Upvotes: 1