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"> {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:
me
gets a new value, so renderme
has a new value, so runuseEffect()
useEffect()
callssetMe()
- 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".