Flutter中Firebase Auth的onAuthStateChanged未检测到登出问题
Hey there, let's figure out why your auth state listener isn't firing when you sign out. That "Notified 0 auth state listeners" log is a big clue—here are the most likely fixes to get this working:
1. Make sure your listener subscription is properly retained
The most common issue here is that your auth state stream subscription got canceled or garbage-collected before you triggered the sign-out.
To fix this, always store the StreamSubscription object in a class-level variable (not a local one) so it stays alive while your widget is active:
class YourAuthWidget extends StatefulWidget { const YourAuthWidget({Key? key}) : super(key: key); @override State<YourAuthWidget> createState() => _YourAuthWidgetState(); } class _YourAuthWidgetState extends State<YourAuthWidget> { // Keep a reference to the subscription StreamSubscription<User?>? _authSubscription; @override void initState() { super.initState(); // Register the listener in initState (not build!) _authSubscription = FirebaseAuth.instance.authStateChanges().listen((user) { print('Auth state changed: ${user?.uid ?? "No user"}'); // Handle your state updates here }); } @override void dispose() { // Cancel the subscription when the widget is destroyed _authSubscription?.cancel(); super.dispose(); } // Rest of your widget code... }
Never register the listener in the build method—every rebuild will create a new subscription, and old ones will be discarded, leading to missing listeners when you need them.
2. Verify your sign-out flow is complete
Even though the log says Firebase is trying to notify listeners, double-check you're signing out of both Google Sign In and Firebase Auth:
Future<void> signOut() async { // Sign out of Google first await GoogleSignIn().signOut(); // Then sign out of Firebase Auth await FirebaseAuth.instance.signOut(); }
While Firebase Auth's sign-out should trigger the state change on its own, ensuring both are signed out prevents edge cases where the Google session lingers and causes unexpected behavior.
3. Confirm you're using the same Auth instance
Make sure you're listening to FirebaseAuth.instance and calling signOut() on the same instance. It's easy to accidentally create a new instance (though rare), which would mean your listener is attached to a different Auth object than the one you're signing out from.
Quick Test to Diagnose
Add a print statement right before you call sign-out to check if the subscription is still active:
Future<void> signOut() async { print('Is subscription active? ${_authSubscription?.isPaused ?? false}'); // Rest of sign-out code... }
If it returns true (paused) or the subscription is null, that confirms your listener was canceled prematurely.
内容的提问来源于stack exchange,提问作者Gilberg

