# #firebase #flutter
Вопрос:
государственное управление слишком сложно.
Вход в систему через firebase работает нормально, и выход из системы хорошо работает в первый раз.
Однако, если вы войдете в систему и перейдете на другой экран, вы не сможете выйти из системы.
Что пошло не так?
- поставщик выхода из системы
»’
Future logout() async {
await firebaseAuth.signOut();
}
»’
- Страницы, использующие выход из системы
»’
Widget build(BuildContext context) {
final loginProvider = Provider.of<AuthProvider>(context);
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
onPressed: () async => await loginProvider.logout(),
icon: Icon(
Icons.settings,
color: Colors.white,
),
)
),
Если я изменю его, как показано ниже, он будет работать нормально.
Но я не знаю, правильный ли это путь.
»’
onPressed: () async => await loginProvider.logout().then(
(value) => Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (BuildContext context) => Wrapper()))),
- Поставщик входа в систему
»’
Future login(String email, String password) async {
setLoading(true);
try {
UserCredential authResult = await firebaseAuth.signInWithEmailAndPassword(
email: email, password: password);
User? user = authResult.user;
setLoading(false);
return user;
} on SocketException {
setMessage('No internet');
} catch (e) {
setLoading(false);
setMessage(e.toString());
}
notifyListeners();
}
»’
»’
- Login Screen
»’
Container(
height: 50.0,
margin: EdgeInsets.only(top: 20.0),
width: MediaQuery.of(context).size.width * 0.8,
child: MaterialButton(
color: Color(0xffe50815),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
onPressed: () async {
if (this._formKey.currentState!.validate()) {
print('email : ${this.idCt.text}');
print('password : ${this.pwCt.text}');
await loginProvider.login(
this.idCt.text.trim(), this.pwCt.text.trim());
}
},
child: loginProvider.isLoading
? CircularProgressIndicator()
: Text("LOGIN",
style: new TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.bold,
color: Colors.white))),
),
»’
- provider
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { final _init = Firebase.initializeApp(); return FutureBuilder( future: _init, builder: (BuildContext context, snapshot) { if (snapshot.hasError) { return Column( children: [ Icon(Icons.error), Center( child: Text('something went wrong!'), ), ], ); } else if (snapshot.hasData) { return MultiProvider( providers: [ ChangeNotifierProvider<AuthProvider>.value( value: AuthProvider(), ), StreamProvider<User?>.value( value: AuthProvider().user, initialData: null, catchError: (_, err) => null, ), ChangeNotifierProvider( create: (BuildContext context) => MovieNowPlayingProvider()), ChangeNotifierProvider( create: (BuildContext context) => TvPopularProvider()), ], child: MaterialApp( debugShowCheckedModeBanner: false, home: SplashScreen(), ), ); } return Container(); }); }
}
- Обертка «‘
class Wrapper extends StatelessWidget { const Wrapper({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final user = Provider.of<User?>(context); if (user != null) { return MainScreen(); } return Authentication(); }
}
»’
Комментарии:
1. Какие ошибки вы получаете?
2. Где определен ваш поставщик логинов?
3. Хорошо. Можете ли вы объяснить эту часть вашего вопроса: «Вход в систему через firebase работает нормально, и выход из системы хорошо работает в первый раз. Однако, если вы войдете в систему и перейдете на другой экран, вы не сможете выйти из системы».?
4. Да, теперь я понимаю. Можете ли вы показать, с помощью какого виджета вы завернули своего провайдера?
5. Нет, дело не в этом. Где вы представили Провайдера? Например
Provider(create: LoginProvider(), lazy: false, child: Widget())
.
Ответ №1:
Использование .then
, а затем переход к оболочке не является неправильным, но вы, возможно, захотите изменить onPressed
код таким образом:
onPressed: () async {
await loginProvider.logout();
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (BuildContext context) => Wrapper())
);
},
Поскольку вы используете async/await
, более последовательно использовать именно это, а не комбинировать с .then
ним .
Комментарии:
1. большое вам спасибо за ответ, однако, notifyListeners(); То же самое верно и для добавления, Неправильно ли использовать LoginProvider.logout().then() ? Выход из системы отлично работает с этим методом.
2. Нет, это не неправильно, но поскольку вы уже слушаете текущего пользователя в своем
Wrapper
, это более правильный метод. Использование.then
и навигация вручную будут похожи на повторение того, что уже было реализовано3. Я понял, что ты имеешь в виду. На данный момент давайте использовать LoginProvider.logout().затем() . Я исправлю это, когда выясню, в чем проблема.
4. Вы имеете в виду, что добавление
notifyListeners()
не решило эту проблему?5. Я увидел обновленный ответ и изменил код. Работает нормально. Спасибо