React Native中Firebase onAuthStateChanged多次触发问题咨询
onAuthStateChanged Triggers in React Native Firebase Auth Hey there, I’ve run into this exact issue before—let’s break down why your onAuthStateChanged is firing multiple times and how to fix that annoying repeated navigation on logout.
Why This Happens
The most common culprit here is uncleaned subscriptions. Every time your component mounts (via componentDidMount), you’re adding a new listener to Firebase Auth’s state changes. If the component unmounts and remounts (like navigating away and coming back), you end up with multiple active listeners. Each one triggers your loginFunc when the auth state changes, leading to duplicate console logs and repeated navigation actions.
The Fix: Clean Up Your Subscription
You need to save a reference to your auth subscription and cancel it when the component unmounts. Here’s how to adjust your code:
componentDidMount() { // Store the subscription reference on your component instance this.authSubscription = fbAuth.onAuthStateChanged(user => this.loginFunc(user)); } componentWillUnmount() { // Cancel the subscription when the component is removed from the screen if (this.authSubscription) { this.authSubscription(); } } loginFunc(user) { if (user) { console.log('LOGGED IN'); // Add your post-login logic here (e.g., navigate to home) } else { console.log('LOGGED OUT'); // Prevent repeated navigation by checking the current route first const currentRoute = this.props.navigation.getCurrentRoute(); if (currentRoute?.name !== 'Login') { // Adjust 'Login' to your actual login screen name this.props.navigation.goBack(); } } }
What’s Changed?
- Saved Subscription Reference: We’re storing the return value of
onAuthStateChanged(which is an unsubscribe function) inthis.authSubscription. - Unmount Cleanup: In
componentWillUnmount, we call that unsubscribe function to remove the listener, so it won’t fire anymore once the component is gone. - Guard Clause for Navigation: Adding a check for the current route ensures we only navigate if we’re not already on the login screen—this adds an extra layer of protection even if there’s a stray trigger.
For Functional Components (Bonus)
If you ever switch to functional components, the fix uses useEffect’s cleanup function, which works the same way:
import { useEffect } from 'react'; function YourComponent({ navigation }) { useEffect(() => { const unsubscribe = fbAuth.onAuthStateChanged(user => { if (user) { console.log('LOGGED IN'); } else { console.log('LOGGED OUT'); const currentRoute = navigation.getCurrentRoute(); if (currentRoute?.name !== 'Login') { navigation.goBack(); } } }); // Cleanup subscription on unmount return unsubscribe; }, [navigation]); // Rest of your component code }
This should stop the multiple triggers and get your login/logout behavior back to working as expected—one fire on login, one on logout.
内容的提问来源于stack exchange,提问作者johanjohansson

