Flutter Firebase Auth – change home widget if the user is logged in

Issue

I’m building an app that supports only google login using google_sign_in package. When the app is run, it first checks if FirebaseAuth is alive. If user in FirebaseAuth.instance.authStateChanges().listen((User? user) is not null, HomePage() should be shown. If the user is null it should go to AuthPage() which has a google sign-in button.

The code for main.dart is shown below.

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();

  Widget _defaultHome = HomePage();

  // Check if user already logged in
  FirebaseAuth auth = FirebaseAuth.instance;

  auth.authStateChanges().listen((User? user) {
    if (user == null) {
      _defaultHome = AuthPage();

    }
    print(user);
  });

  runApp(MultiProvider(
    providers: [
      ChangeNotifierProvider(create: (_) => SignInProvider()),
      ChangeNotifierProvider(create: (_) => DataProvider()),
    ],
    child: new MaterialApp(
      title: 'Mentea',
      home: _defaultHome,
      routes: {
        'auth': (context) => AuthPage(),
        'home': (context) => HomePage(),
      },
    ),
  ));
}

But when I run it, console gives

I/flutter (14933): null

which means no logged in user, but the emulator shows HomePage() instead of AuthPage(). Anybody know how to fix this? I tried changing ‘home:’ attribute to ‘initialRoute:’, but it doesn’t work either (directs to HomePage() while printing null).

String _defaultHome = 'home';
...
  auth.authStateChanges().listen((User? user) {
    if (user == null) {
      _defaultHome = 'auth;
    }
  });
...
    child: new MaterialApp(
      title: 'Mentea',
      initialRoute: _defaultHome,
      routes: {
        'auth': (context) => AuthPage(),
        'home': (context) => HomePage(),
      },
    ),

Solution

We can assign a StreamBuilder that listens to FirebaseAuth state changes, to the home property:

StreamBuilder(
  stream: FirebaseAuth.instance.onAuthStateChanged,
  builder: (user) {
    return user == null ? AuthPage() : HomePage(),
  }
),

Follows a full example:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MultiProvider(
    providers: [
      ChangeNotifierProvider(create: (_) => SignInProvider()),
      ChangeNotifierProvider(create: (_) => DataProvider()),
    ],
    child: MaterialApp(
      title: 'Mentea',
      home: StreamBuilder(
        stream: FirebaseAuth.instance.onAuthStateChanged,
        builder: (user) {
          return user == null ? AuthPage() : HomePage(),
        },
      ),
      routes: {
        'auth': (context) => AuthPage(),
        'home': (context) => HomePage(),
      },
    ),
  ));
}

Answered By – Stefano Amorelli

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published