Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I created a react native app and have to refresh my screen every time in order to get the newly added data from firebase. I am using hooks

I created a react native app and have to refresh my screen every time in order to get the newly added data from firebase. I'm new to firebase and I thought I can use snapshot to get the current data but I still have to refresh my app every time a new event is created in order to see all the updated events on this view. Any help would be appreciated

export default function EventsHostedScreen() {
    const navigation = useNavigation();
    const [eventsData, setEventsData] = useState([]);

    useEffect(() => {
        async function fetchData() {
            const currentUser = await firebase.auth().currentUser.uid;
            result = [];

            const eventsCollection = firebase.firestore().collection('events');

            eventsCollection.get().then((snapshot) => {
                snapshot.docs.forEach((doc) => {
                    if (doc.exists === true && doc.data().userId !== null) {
                        if (doc.data().userId === currentUser) {
                            result.push(doc.data());
                        }
                    }
                });
                setEventsData(result);
            });

            console.log('RESULT==>', result);
        }

        fetchData();
    }, []);
like image 448
serenity8468 Avatar asked Sep 20 '25 00:09

serenity8468


1 Answers

You can listen to changes to a document or collection with the onSnapshot method. In addition to that, I would suggest a couple of changes to your code.

It seems to me like you want to query for documents where the userId is same as the current user's id. It would be easier to include this in the query with the where method. That way you won't have to filter the documents with if statements like you currently are. You will also save on Firestore reads, as right now you are getting all events, but with the where method you will only read the documents where the equality clause is true.

I would also include a check for whether you have the currentUser available, unless you are 100% sure this component won't ever be rendered while the currentUser is loading. And you don't need to await the currentUser and therefore don't need an async function anymore.

With these changes your useEffect could look something like the following.

useEffect(() => {
  // Check if currentUser exists to avoid errors
  if (!firebase.auth().currentUser) {
    return;
  }

  const currentUser = firebase.auth().currentUser.uid;

  // Create subscription to listen for changes
  const unsubscribe = firebase
    .firestore()
    .collection('events')
    .where('userId', '==', currentUser)
    .onSnapshot((snapshot) => {
      const result = [];
      snapshot.forEach((doc) => {
        result.push(doc.data());
      });

      setEventsData(result);
    });

  // Remove the listener when component unmounts
  return () => unsubscribe();
// Add currentUser to useEffect dependency array, so useEffect runs when it changes
}, [firebase.auth().currentUser]);
like image 146
Santeri Sarle Avatar answered Sep 21 '25 14:09

Santeri Sarle