Search code examples
firebasereact-nativegoogle-cloud-firestoreexporeact-native-flatlist

React Native combine 2 Firestore collection in one Flatlist


I have 2 collections in Firestore to do FeedScreen like this

collection users (when user register App)

users = [
    avatar: '',
    email: '',
    name: ''
]

collection Post (when user create a post)

posts = [
   image: '',
   text: '',
   timestamp: '',
   uid: ''
]

I do useState with collection posts like this

const [loading, setLoading] = useState(true);
const [post, setPost] = useState([]); // Initial empty array of users

useEffect(() => {
  const subscriber = firebase
    .firestore()
    .collection("posts")
    .orderBy("timestamp", "desc")
    .onSnapshot((querySnapshot) => {
      const post = [];

      querySnapshot.forEach((doc) => {
        post.push({
          key: doc.id,
          name: doc.data().name, //want name from collection users
          text: doc.data().text,
          timestamp: doc.data().timestamp,
          avatar: { uri: doc.data().avatar }, //want avatar from collection users
          image: { uri: doc.data().image },
        });
      });

      setPost(post);
      setLoading(false);
    });

  // Unsubscribe from events when no longer in use
  return () => subscriber();
}, []);

if (loading) {
  return <ActivityIndicator />;
}

And the Flatlist

<FlatList
  style={styles.feed}
  data={post}
  renderItem={({ item }) => this.renderPost(item)}
  keyExtractor={(item) => item.key}
  showsVerticalScrollIndicator={false}
/>;

I try to useState collection('users') and combine it with map but it gives error

I would like to display feed to flatlist with all of the data in the post and fetch avatar and name from users collection.


Solution

  • You should create a new array from 2 collection lists, .data is what you need in the below example.

    const users = [
      {
        id: “”,
        avatar: “ “ ,
        email : “ “ ,
        name: ""
      },
    ];
    
    const post = [
      {
        image: "", 
        text: "", 
        timestamp: ,, 
        uid: ""
      }
    ];
    
    
    const collectionUsers = {}:
    users.forEach((item) => {
      if(collectionUsers[item.id] {
         collectionUsers[item.id] += item.avatar;
      } else {
        collectionUsers[item.id] = item.avatar;
      }
    });
    
    
    const data = post.map((item) => ({
       … item,
       avatar: collectionUsers[item.id]
    })):
    
    console.log(data);
    
    
    <FlatList 
           data={post}
           keyExtractor={(item, index) => String(index)} 
           renderItem={({ item }) => ( 
                   <View> 
                         <Text> 
                                {item.avatar} 
                        </Text> 
                  </View> 
          )} 
      />
    

    Additional documentation that could help you:

    https://www.tutorialguruji.com/javascript/combine-multiple-firestore-collection-in-one-flatlist-in-react-native/

    https://rnfirebase.io/firestore/usage-with-flatlists

    https://medium.com/@harshita.arun.1/firebase-to-flatlist-react-native-5281718969ab