Search code examples
reactjsfirebasereact-nativefirebase-realtime-databaseuse-effect

Results from realtime db not available when called


Im having some trouble with realtime database and react native. I have the following useEffect in a component that is supposed to listen for changes and then update state as required, I then use that state to populate a list.

The component gets a data object passed as a prop, the data object contains a string array called members that contains uuids, I am trying to iterate over those to get the attached user from realtime db and then save those objects to a state array.

const myComponent = ({ data }) => {
 const [users, setUsers] = useState([]);
 
 useEffect(() => {
            const userArr = [];
            data.map(item => {
                item.members.forEach((username: string) => {
                    database()
                        .ref(`users/${username}`)
                        .on('value', snapshot => {
                            userArr.push(snapshot.val());
                        });
                });
            });
            setUsers(userArr);
        };
    }, []);

return (
  <>
   {users} <-----  this is in a flatlist
  </>
 );
}

It works eventually after refreshing the screen about 5 times. Any help would be greatly appreciated.


Solution

  • The simplest way to get some data to show is to move update the state right after you add an item to the array:

    useEffect(() => {
      const userArr = [];
      data.map(item => {
          item.members.forEach((username: string) => {
              database()
                  .ref(`users/${username}`)
                  .on('value', snapshot => {
                      userArr.push(snapshot.val());
                      setUsers(userArr); // 👈
                  });
              });
          });
      };
    }, []);
    

    Now the UI will update each time that a user is loaded from the database.

    I also recommend reading some more about asynchronous loading, such as in Why Does Firebase Lose Reference outside the once() Function?