Home > Mobile >  React Firebase UseEffect Firestore
React Firebase UseEffect Firestore

Time:06-06

I've got a user bar component directly adjacent to my navbar, showing avatar and display name (user details saved within a userid-named doc). I followed the firestore documentation for real time updates. Placed inside a use effect hook, which has a dependency array, but is firing repetitively, firing off about 4,000 calls a minute per logged in user).

I really just want the snapshot to update when a user updates their display name or avatar. (found on a different form component)

I console logged every useEffect hook in my project to narrow it down to this component. Is there something about the dependency array causing this? Is there a better way to write this? Thanks!

export default function UserBar() {
    const { user } = useAuthContext()
    const [me, setMe] = useState([])

  useEffect(() => {

    //user real-time subscription for avatar and displayname
    const auth = getAuth()
    const fireUser = auth.currentUser

    const unsub = onSnapshot(doc(db, "users", fireUser.uid), (doc) => {

        if (doc.exists()) {
            setMe(doc.data())
            console.log('looking for duplicate - userbar unsub')
        } else {
            console.log("No such document!")
        }
    })
    return () => unsub()
  }, [me])

  return ( 
    <>
        {user && (
            <div className="user-bar">
                <p className="oneHunid">Welcome
                    <span className="bold">&nbsp;&nbsp;{user.displayName}!</span>
                </p>
                <Avatar src={me.photoURL} />
            </div>
        )}
    </>
  )
}

CodePudding user response:

You do not want to have [me] as a dependency when inside the useEffect() you call setMe(). That leads to an infinite loop:

  1. me gets a new value, so render
  2. me has a new value, so run useEffect()
  3. useEffect() calls setMe()
  4. go to # 1

Based on the above, it looks like what you really want is to have your useEffect() be dependent on the value of auth.currentUser. So get that value outside of the useEffect() and then check to be sure it is not null. If it is not null, then start the onSnapshot() listener.

BTW: if it would be of help, check out the user profiles with Firebase Auth project I developed. In particular, check out the FirebaseProvider.js which is where I configure the Firebase project and get all of its services, and AuthProvider.js which provides login, logout, registration and "user profile".

  • Related