0
import React, { useEffect, useState } from "react";
import { View, Text, StyleSheet, Image, FlatList } from "react-native";
import PostComponent from "../../Components/PostComponent";
import { db } from "../../firebase";
import {
  collection,
  query,
  getDocs,
  orderBy,
  doc,
  getDoc,
} from "firebase/firestore";

const postData = [];
const firstData = [];

async function getPosts() {
  const q = query(collection(db, "Posts"), orderBy("postTime"));
  const querySnapshot = await getDocs(q);
  querySnapshot.forEach((postDatas) => {
    const dataPost = postDatas.data();
    firstData.push({ id: postDatas.id, dataPost });
    
  });
}
const getUserDetails = async (a, b) => {
  const docRef = doc(db, "Users", a.creator);
  const docSnap = await getDoc(docRef);

  if (docSnap.exists()) {
    const userDetails = docSnap.data();
    postData.push({ id: b, ...a, ...userDetails });
    console.log("1st: " + postData);
    
  } else {
    
    console.log("No such document!");
  }
};

function Posts() {
  const [loading, setLoading] = useState(true);
  useEffect(() => {
    getPosts()
      .then(() => {
        console.log("Get Posts Complete");
        console.log(firstData.length);
        firstData.forEach((a) => getUserDetails(a.dataPost, a.id));
      })
      .then(() => console.log("2nd " + postData))
      .catch((e) => console.log(e));
  }, []);

  const renderPosts = ({ item }) => <PostComponent />;

  if (loading) {
    getPosts();
    return <Text>Loading Posts</Text>;
  }
  return (
    <View>
      <FlatList data={postData} renderItem={renderPosts} />
    </View>
  );
}

const styles = StyleSheet.create({});

export default Posts;

I refer to the code above.

What I am trying to achieve is to retrieve documents from the User collection based on result from the Post collections. However, I want the console.log("1st: " + postData); in the getUserDetails function to run before the console.log("2nd " + postData). But every time I run the code, the second one runs first before the first. This is a dilemma to me as I thought the first then is supposed to completely run before moving to the second then. Kindly help

yusufamo
  • 7
  • 5
  • don't post questions with titles in ALL CAPS ... nobody will answer – Bravo May 03 '22 at 12:08
  • Don't put the `postData` in an array outside the component. Use state. – evolutionxbox May 03 '22 at 12:09
  • You are not `await`ing `getUserDetails` - which you could if you'd pass a self-invoked async function instead of `then`ing (and also use `for of` instead of `forEach`). Or, if you wanted to do those things in parallel, you'd simply have to use `return Promise.all(firstData.map(...))` instead of `firstData.forEach(...)`. – CherryDT May 03 '22 at 12:09
  • 1
    `firstData.forEach((a) => getUserDetails(a.dataPost, a.id));` asynchronous code in a forEach is NEVER going to do what you want – Bravo May 03 '22 at 12:10

0 Answers0