Terrace Grow
Terrace Grow

Reputation: 21

Firestore data in a flatlist with react native

I've been trying to output data from my Firestore db to a Flatlist in React native but so far unsuccesfull.

I've used this Flatlist for RN and Firestore docs as reference to getting started but for some reason I am missing something here regarding the output method of the Flatlist because it wont output the flatlist itself. When I console log the locations array it shows me all the docs inside that i've queried so it does push them all into an array and my understanding is of FlatLists that they need an array to function but it does not throw any error just doesn't render. Any help more than welcome!


    useEffect(async () => {
        const locations = [];
        const querySnapshot = await getDocs(collection(db, "Location"));
        querySnapshot.forEach((doc) => {
          // doc.data() is never undefined for query doc snapshots
            locations.push(doc.data());
          console.log(locations);
        }); 
        return () => querySnapshot();
    }, []);
    

    return (
        <View style={styles.screen}>
            <Text>hello</Text>
            <FlatList data={locations}
                renderItem={({ item }) => (
                    <View >
                        <Text>name: {item.name}</Text>
                        <Text>Depth: {item.depth}m</Text>
                        <Text>GeoLocation: {item.geo}</Text>
                        <Text>id: {item.uid}</Text>
                    </View>
                )}
            />

Upvotes: 0

Views: 1130

Answers (2)

Osman Khalid
Osman Khalid

Reputation: 798

Here is a simple way:

import React, {useState} from 'react';
import { Button, View, Text, FlatList } from 'react-native';

import {query, where,  collection, getDocs } from 'firebase/firestore';

import {db} from './firestoreconfig.js';

const App = () => {
   const [cities, setCities] = useState([]);

   async function readData() 
   {
      setCities([]);
     const mycities = [];
     const q = query(collection(db, "cities"), where("capital", "==", true) );
     const querySnapshot = await getDocs(q);     
     querySnapshot.forEach( (city) => {mycities.push({key: city.id, name: city.data().name} )})   
     
     setCities(mycities);
     
   }
  return (

<View
style = {{marginTop: 50}}
>   
   <Button   
   title='Read Data'
   onPress={ () => readData()} 
    />

         <FlatList 
         data={cities}
        
        renderItem = { 
            
            ({item}) => 
            <Text>{item.key} {item.name}</Text> 
            
    }
    />

    </View>
   );
}

export default App;

Upvotes: 0

David Scholz
David Scholz

Reputation: 9856

Your variable locations is defined in your useEffect. The FlatList can not access it. You need to create a state via useState and store the data in there once it is loaded. Setting the state will cause a rerendering of the component and the FlatList will be updated with the new data.

Here is one possible implementation.

const SomeScreen = () => {

    const [locations, setLocations] = useState([])

    useEffect(() => {
        const loadData = async () => {
            const querySnapshot = await getDocs(collection(db, "Location"));
            setLocations(querySnapshot.map(doc => doc.data()))
        }

        loadData()
    }, [setLocations]);
    

    return (
            <FlatList data={locations}
                renderItem={({ item }) => (
                    ...
                )}
            />
   )
}

Upvotes: 1

Related Questions