Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Display all posts from database

I have a Firestore collection, schemed as follows:

posts{
    uid{
        userPosts{
            postID{
                creation:
                postText:
            } 
        }
    }
}

I want to display all of the posts, so I’ve made the corresponding queries and saved them in posts – an array of all the posts that I later iterate through.

The problem with the way I do it is that it keeps adding the same posts every render. So I’ve tried to set the array each time, but that way the code never passes through these posts && posts.length > 0 condition.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I’m really new to RN and JS in general, but what I was expecting is

Nothing to show here

at first, and then the list of posts.

The complete component:

import { Text, Pressable, FlatList, SafeAreaView } from "react-native";
import { globalStyles } from "../../styles/global";
import React, { useState, useEffect } from "react";
import { db } from "../../../firebase";
import Post from "../../API/Post";
import { collection, getDocs } from "firebase/firestore";

const FeedScreen = ({ navigation }) => {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    const getPostData = async () => {
      setPosts([]); // ---> Without this line the posts keeps adding each render
      const q = collection(db, "posts");
      const docSnap = await getDocs(q);
      docSnap.docs.map(async (item) => {
        const tmp = collection(db, "posts", item.id, "userPosts");
        const tmpSnap = await getDocs(tmp);
        tmpSnap.docs.map(async (element) => {
          setPosts((prev) => {
            prev.push(element.data());
            return prev;
          });
        });
      });
    };

    getPostData().catch(console.error);
    return;
  }, []);

  return (
    <SafeAreaView style={globalStyles.global}>
      {posts && posts.length > 0 ? (
        <FlatList
          data={posts}
          renderItem={({ item }) => (
            <Post
              post={item}
              navigation={navigation}
              style={globalStyles.list_of_posts}
            />
          )}
          keyExtractor={(item, index) => index.toString()}
        />
      ) : (
        <Text>Nothing to show here</Text>
      )}

      <Pressable
        title="edit"
        onPress={() => {
          navigation.navigate("CreatePost", { navigation });
        }}
        style={globalStyles.plus_btn}
      >
        <Text style={globalStyles.plus_btn_text}>+</Text>
      </Pressable>
    </SafeAreaView>
  );
};

export default FeedScreen;

As said, I’m new to this so I’d love an explanation of what actually happens and how to do it properly.

>Solution :

I think the prev value of setPosts will always be [] since it does not immediately update if you call it. A standard way to do it is to call setPosts at the end of your function. Can you try this one?

useEffect(() => {
    const getPostData = async () => {
      const q = collection(db, "posts");
      const docSnap = await getDocs(q);
      const promises = docSnap.docs.map(async (item) => {
        const tmp = collection(db, "posts", item.id, "userPosts");
        const tmpSnap = await getDocs(tmp);
        return tmpSnap.docs.map((element) => element.data());
      });
      const arrayOfPosts = await Promise.all(promises);
      let newPosts = [];
      arrayOfPosts.forEach((posts) => {
        newPosts = [...newPosts, ...posts];
      });
      setPosts(newPosts);
    };

    getPostData().catch(console.error);
    return;
  }, []);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading