在 Flutter 中使用 Firebase/Google 登录时无法注销并重定向到 LoginPage

Posted

技术标签:

【中文标题】在 Flutter 中使用 Firebase/Google 登录时无法注销并重定向到 LoginPage【英文标题】:Can't Logout and redirect to LoginPage when using Firebase/ Google Sign-in in Flutter 【发布时间】:2020-01-09 17:50:21 【问题描述】:

我正在实施一个使用 Firebase 身份验证和 Google-Sign 的 Flutter 应用。我已经成功地让 firebaseauth 正常登录/注销。根据 authstate 的变化,我直接到主页或登录页面。然后我实现了 Google Sign-in,它会自动将用户登录到 firebase。

这有效,我获得了提示等必要的权限。但是当我点击注销时,应用程序不会重定向到登录屏幕。我正在调用 await firebaseAuth.instance.Signout() ...我相信它确实会删除用户..但它不会重定向。然后,当我再次尝试登录时,什么也没有发生。

我已经尝试了许多不同的登录变体。我似乎无法弄清楚为什么它不会在注销时重定向。

这是我登录 Google 和 firebase 的登录逻辑:

    try 
    final GoogleSignInAccount googleSignInAccount =
       await _googleSignIn.signIn();
   final GoogleSignInAuthentication googleSignInAuthentication =
      await googleSignInAccount.authentication;

  final AuthCredential credential = GoogleAuthProvider.getCredential(
    accessToken: googleSignInAuthentication.accessToken,
    idToken: googleSignInAuthentication.idToken,
  );

  final FirebaseUser user = await _firebaseAuth.signInWithCredential(credential);

  assert(!user.isAnonymous);
  assert(await user.getIdToken() != null);

  final FirebaseUser currentUser = await _firebaseAuth.currentUser();
  assert(user.uid == currentUser.uid);
 catch (error) 
  print(error);

notifyListeners();

这是我在 main.dart 中重定向到适当页面的逻辑:

    home: StreamBuilder(
        stream: _firebaseAuth.onAuthStateChanged,
        builder: (context, snapshot) 
          if(snapshot.hasData)
            return HomePage();
           else 
            return Login();
          
        ,
      )

这是我对 Signout() 的逻辑

   Future<void> signOut() async 
   await _firebaseAuth.signOut().catchError((error)
   print(error.toString());
   );
   

就我而言,我不想让用户从 Google 中注销,而只是我的应用程序。 但我无法弄清楚为什么这不会重定向。当我使用带有电子邮件/密码的标准 Firebase 登录时,它可以正常工作。

【问题讨论】:

托盘添加 notifyListeners();在等待 _firebaseAuth.signOut() 之后 是的,已经尝试过了……没区别。我实际上还发现,它并没有在这里注销firebase用户......点击注销后,我回到现有屏幕并且用户仍然登录?很奇怪。还有其他想法吗? @mikehennessy 与问题无关,你是如何设置谷歌登录的。我已经填写了同意书,但仍然无法使用 【参考方案1】:

这适用于FlutterFire。我在 FirebaseAuth 实例和 Navigator 上使用了 authStateChanges() 方法。

authStateChanges() 方法可以让你获取用户的认证状态。

Firebase 身份验证使您能够通过 溪流。一旦被调用,流会提供一个即时事件 用户当前的认证状态,然后提供后续的 身份验证状态更改时的事件。

Navigator 用于导航到 main.dart

要切换到新路由,请使用 Navigator.push() 方法。推() 方法将 Route 添加到由 Navigator 管理的路由堆栈中。

main.dart

import 'package:firebase_auth/firebase_auth.dart' as auth;
import 'package:flutter/material.dart';
import 'menu.dart';
import 'login.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:firebase_core/firebase_core.dart';

Future main() async 
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(
    MyApp()
  );


class MyApp extends StatelessWidget 

  @override
  Widget build(BuildContext context) 
    SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitUp]);
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'TestApp',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: 
        StreamBuilder<auth.User>(
          stream: auth.FirebaseAuth.instance.authStateChanges(),
          builder: (BuildContext context, AsyncSnapshot<auth.User> snapshot)  
            if(snapshot.hasData) 
              print("There is a user logged in");
              return HomePage();
            
            else 
              return LoginPage();
            
          ,
        )
    );
  

使用 Firebase 身份验证退出

Future<void> signOut() async 
   await _firebaseAuth.signOut().catchError((error)
       print(error.toString());
   );
   Navigator.push(context, MaterialPageRoute(builder: (context) => MyApp()));

【讨论】:

【参考方案2】:

经过大量挖掘,事实证明,如果您从 sideDrawer 组件调用 SignOut(),则不能只调用 Signout。你需要这样做。帮我解决了。

    FlatButton(
        child: Text('Logout'),
        onPressed: () 
          Navigator.of(context).pop();
          Navigator.of(context).pushReplacementNamed('/');
          Provider.of<Auth>(context).signOut();
        ,
      ),

【讨论】:

天哪,非常感谢。很多小时后找到了你的答案。我也在使用带有退出按钮的侧抽屉【参考方案3】:

我认为只能像这样在 _googleSignIn 上进行 singOut:

Future<void> signOut() async 
   await _firebaseAuth.signOut().catchError((error)
       print(error.toString());
   );
   await _googleSignIn.signOut();

【讨论】:

所以,我刚刚使用类似的 Bloc 尝试了这个 felangel.github.io/bloc/#/flutterfirebaselogintutorial,看看,也许它可以帮助你。 我没有看到任何可以识别任何问题的东西......这真的很奇怪。

以上是关于在 Flutter 中使用 Firebase/Google 登录时无法注销并重定向到 LoginPage的主要内容,如果未能解决你的问题,请参考以下文章

firebase“长链接不可解析”

flutter系列之:在flutter中使用导航Navigator

Flutter - 无法在flutter web中使用动态链接

在 Flutter Web 中使用 Flutter 移动包

如何使用 flutter_webview 插件在 Flutter 中启用位置?

在flutter中使用Chopper网络库和flutter_bloc库