Контекст
Я пытаюсь создать приложение, используя Flutter , которое требует от пользователей регистрации и / или входа . Используя провайдера, я мог при каждом запуске приложения определять, был ли пользователь уже авторизован или нет, показывая соответственно MainScreen
или SignInScreen
, как вы можете видеть из приведенного ниже кода.
void main() {
runApp(Stuff());
}
class Stuff extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
StreamProvider<FirebaseUser>.value(value: AuthService().onAuthChanged),
],
child: Consumer<FirebaseUser>(builder: (context, user, _) {
return MaterialApp(
title: 'Stuff',
home: user != null ? MainScreen() : SignInScreen(),
routes: {
'/main_screen' : (context) => MainScreen(),
'/signup_screen': (context) => SignUpScreen(),
'/signin_screen': (context) => SignInScreen(),
},
);
}),
);
}
}
, где AuthService на данный момент выглядит следующим образом:
class AuthService{
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
@override
Stream<FirebaseUser> get onAuthChanged => _firebaseAuth.onAuthStateChanged;
}
Если пользователь не вошел в систему, то отображается SignInScreen
, а после процесса входа StreamProvider
уведомляется правильно, и свойство home
обновлений MaterialApp
автоматически показывает MainScreen
.
Проблема
Когда пользователи попадают в SignInScreen
, у них есть выбор: войдите в систему или перейдите к другому SignUpScreen
на зарегистрируйтесь ( экран приложения ), например:
GestureDetector(
child: Text('Sign Up.'),
onTap: () {
Navigator.pushReplacementNamed(context, '/signup_screen');
},
),
Если они выберут для входа, когда они будут выполнены, home
будет правильно обновлен и MainScreen
отображается, как я сказал выше. Но если они решат зарегистрироваться, , когда они закончили, ничего не происходит. Все слушатели уведомляются, но StreamProvider
не получает это уведомление. Единственная причина, по которой я могу придумать такое поведение, заключается в том, что SignUpScreen выходит за рамки провайдера, но дерево виджетов, похоже, предполагает, что это так.
Дерево виджетов
Возможно, проблема в pushReplacementNamed
?
PS: Я должен упомянуть, что GestureDetector
является частью следующего метода, который я передаю свойству appBar
объекта Scaffold
.
PreferredSize _buildAppBar() {
return PreferredSize(
preferredSize: Size.fromHeight(MediaQuery.of(context).size.height * 0.18),
child: Container(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.18),
padding: EdgeInsets.only(left: 45.0, right: 45.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Sign In'),
SizedBox(
height: 2.5,
),
Row(
children: [
Text('Have an account already?'),
SizedBox(
width: 4.0,
),
GestureDetector(
child: Text('Sign In.'),
onTap: () {
Navigator.pushReplacementNamed(context, '/signin_screen');
},
),
],
),
],
),
),
);
}