Flutter Firebase Auth — изменение виджета «Главная страница», если пользователь вошел в систему

# #firebase #flutter #dart #firebase-authentication

Вопрос:

Я создаю приложение, которое поддерживает только вход в систему Google с помощью google_sign_in пакета. Когда приложение запускается, оно сначала проверяет, работает ли FirebaseAuth. Если значение user in FirebaseAuth.instance.authStateChanges().listen((User? user) не равно нулю, HomePage() должно быть показано. Если пользователь имеет значение null, он должен перейти на страницу авторизации (), на которой есть кнопка входа в Google.

Код для main.dart этого показан ниже.

 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(),
      },
    ),
  ));
}
 

Но когда я запускаю его, консоль выдает

 I/flutter (14933): null
 

это означает, что пользователь не вошел в систему, но эмулятор показывает домашнюю страницу() вместо AuthPage(). Кто-нибудь знает, как это исправить? Я попытался изменить атрибут «home:» на » initialRoute:», но он тоже не работает (перенаправляет на домашнюю страницу() при печати 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(),
      },
    ),
 

Ответ №1:

Мы можем назначить StreamBuilder свойство, которое прослушивает FirebaseAuth изменения состояния, home свойству:

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

Ниже приведен полный пример:

 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(),
      },
    ),
  ));
}
 

Комментарии:

1. Спасибо! Не знал о построителе потоков. Похоже, onAuthStateChanged устарел. Вместо этого я использовал authStateChanges ().