сбой выхода из системы flutter firebase

# #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. Я увидел обновленный ответ и изменил код. Работает нормально. Спасибо