Flutter google 登录 保持登录状态

Posted

技术标签:

【中文标题】Flutter google 登录 保持登录状态【英文标题】:Flutter google sign in stay logged in 【发布时间】:2019-06-10 08:24:54 【问题描述】:

我已经实现了 firebase auth google 登录,但是我如何在应用程序关闭后保持登录状态,我什至输入了这一行 await _auth.currentUser() 但仍然无法正常工作。下面是我的登录代码。

LoginPage.dart (旧)

import 'package:flutter/material.dart';

import 'package:firebase_auth/firebase_auth.dart';

//Google provider
import 'package:google_sign_in/google_sign_in.dart';
import 'package:flutter_facebook_login/flutter_facebook_login.dart';
import 'package:flutter_auth_buttons/flutter_auth_buttons.dart';

final FirebaseAuth _auth = FirebaseAuth.instance;
final GoogleSignIn _googleSignIn = new GoogleSignIn();

class LoginPage extends StatefulWidget 
    @override
    _LoginPageState createState() => _LoginPageState();


class _LoginPageState extends State<LoginPage> 
String _email;
String _password;
GoogleSignInAccount _currentUser;

@override
void initState() 
  super.initState();
  _googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount account) 

  setState(() 
    _currentUser = account;
  );
  if (_currentUser != null) 
    //_handleGetContact();
  
);
_googleSignIn.signInSilently();


//google sign in
GoogleSignIn googleAuth = new GoogleSignIn();

//Facebook sign in
FacebookLogin fbLogin = new FacebookLogin();

Future<FirebaseUser> _testSignInWithGoogle() async 
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth =
    await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.getCredential(
  accessToken: googleAuth.accessToken,
  idToken: googleAuth.idToken,
);
final FirebaseUser user = await _auth.signInWithCredential(credential);
assert(user.email != null);
assert(user.displayName != null);
assert(!user.isAnonymous);
assert(await user.getIdToken() != null);

final FirebaseUser currentUser = await _auth.currentUser();
assert(user.uid == currentUser.uid);

print('Signed in as $user.displayName');
Navigator.of(context).pushReplacementNamed('/homepage');

return await _auth.currentUser();


void _facebookLogin() async 
var facebookLogin = FacebookLogin();
var facebookLoginResult =
    await facebookLogin.logInWithReadPermissions(['email', 
'public_profile']);

 switch (facebookLoginResult.status) 
  case FacebookLoginStatus.error:
    print("Error");
    onLoginStatusChanged(false);
    break;
  case FacebookLoginStatus.cancelledByUser:
    print("CancelledByUser");
    onLoginStatusChanged(false);
    break;
  case FacebookLoginStatus.loggedIn:
    print("LoggedIn");
    onLoginStatusChanged(true);

    FacebookAccessToken myToken = facebookLoginResult.accessToken;
    AuthCredential credential= 
FacebookAuthProvider.getCredential(accessToken: myToken.token);
    try 
      final FirebaseUser user = await 
FirebaseAuth.instance.signInWithCredential(credential);

      //Navigator.pushReplacement(context, MaterialPageRoute(builder: 
(context) => DiscoverPage()));
      print('Signed in as $user.displayName');
      Navigator.of(context).pushReplacementNamed('/homepage');
     catch (e) 
      debugPrint("Facebook signin error: " + e.toString());
    
    break;



bool isLoggedIn = false;

void onLoginStatusChanged(bool isLoggedIn) 
setState(() 
  this.isLoggedIn = isLoggedIn;
);





LoginPage.dart (新)

class _LoginPageState extends State<LoginPage> 
bool loading = false;

bool isLoggedIn = false;

void onLoginStatusChanged(bool isLoggedIn) 
setState(() 
  this.isLoggedIn = isLoggedIn;
);


@override
void initState() 
super.initState();
isSignedIn();


void isSignedIn() async 
setState(() 
  loading = true;
);

isLoggedIn = await _googleSignIn.isSignedIn();

if (isLoggedIn) 
  Navigator.pushReplacement(
      context, MaterialPageRoute(builder: (context) => HomePage()));


setState(() 
  loading = false;
);


我必须添加此代码才能保持登录状态。顺便问一下,我如何才能为 Facebook 做同样的事情?

【问题讨论】:

【参考方案1】:

查看google_sign_in example,下面的sn-p可能是解决你问题的关键。

  @override
  void initState() 
    super.initState();
    _googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount account) 
      setState(() 
        _currentUser = account;
      );
      if (_currentUser != null) 
        _handleGetContact();
      
    );
    _googleSignIn.signInSilently();
  

我已经实现并测试了它,它按预期工作。

【讨论】:

嗨!感谢您回答我的问题,但仍然无法正常工作。请问我应该把sn-p放在哪里?它应该在登录页面还是主页中?谢谢 把它放在你使用google登录的页面的初始化方法中。例如,如果你在登录页面使用google登录,并且root是StatefulWidget,把它放到initState() 对不起,我已经更新了我的代码,但没有告诉你。对吗? 差不多吧,创建GoogleSignIn实例时不需要指定scopes参数吗?我发现您的代码中有不止一个 GoogleSignInAccount 实例。可能,您应该使用非空 _currentUser 来获取 GoogleSignInAuthentication 的东西,而不是再次登录。 你的意思是这个范围? GoogleSignIn _googleSignIn = GoogleSignIn( scopes: &lt;String&gt;[ 'email', 'https://www.googleapis.com/auth/contacts.readonly', ], );。一直卡在登录状态,是路由问题吗?你能帮我检查一下代码吗?谢谢【参考方案2】:
Future googleSignIn() async 
try 
  GoogleSignInAccount googleUser = await _googleSignIn.signIn();
  GoogleSignInAuthentication googleAuth = await googleUser.authentication;

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

  FirebaseUser _user = (await _auth.signInWithCredential(credential)).user;
  assert(_user.email != null);
  assert(_user.displayName != null);
  assert(!_user.isAnonymous);
  assert(await _user.getIdToken() != null);


    DatabaseServices(uid:_user.uid,email: _user.email)
        .updateUserData(_user.displayName,_user.photoUrl);

  print("signed in " + _user.displayName + "\n" + _user.photoUrl);

  return _user;
 catch (e) 
  print(e.toString());
  return null;

【讨论】:

GoogleAuthProvider.getCredentialAPI 改为GoogleAuthProvider.credential【参考方案3】:

我个人在稳定频道发布 Flutter 后没有尝试过,但您可以存储从 auth 令牌获得的用户信息。

也看看这个:https://medium.com/flutterpub/flutter-how-to-do-user-login-with-firebase-a6af760b14d5

【讨论】:

以上是关于Flutter google 登录 保持登录状态的主要内容,如果未能解决你的问题,请参考以下文章

我是 Flutter Web 的新手,如何使用 Firebase 电话身份验证对用户进行身份验证,有没有办法让用户保持登录状态?

如何使用共享首选项让用户保持登录状态?

Flutter Web:保持用户登录/记住我功能的正确方法

测试保持与Rspec签署

在 Flutter 中保存登录 google 时出错 [重复]

Flutter Authentication 从登录屏幕到登录屏幕使用 Google 登录和注销