You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中Google登录状态重启APP后丢失的解决求助

解决Flutter Google登录重启后账户信息丢失的问题

问题根源

你只通过SharedPreferences存储了isLoggedIn状态标记,但没有持久化Google账户的具体信息;同时APP重启后没有主动验证并恢复Google的登录会话,导致controller.googleAccount.value为空。

解决方案

1. 持久化完整的Google账户信息

登录成功后,除了设置isLoggedIn,还要将Google账户的核心字段(如ID、昵称、邮箱、头像地址)序列化为JSON,存储到SharedPreferences中:

// 登录成功后的处理逻辑
final GoogleSignInAccount? account = await controller.login();
if (account != null) {
  final prefs = await SharedPreferences.getInstance();
  // 将账户信息转为Map后序列化存储
  final accountData = {
    'id': account.id,
    'displayName': account.displayName,
    'email': account.email,
    'photoUrl': account.photoUrl,
  };
  await prefs.setString('google_account', jsonEncode(accountData));
  await prefs.setBool('isLoggedIn', true);
}

2. APP启动时恢复登录状态与账户信息

在APP初始化阶段(比如主页面的initState、全局状态初始化逻辑),先尝试静默登录验证会话有效性,再结合本地存储恢复状态:

@override
void initState() {
  super.initState();
  _restoreLoginState();
}

Future<void> _restoreLoginState() async {
  final prefs = await SharedPreferences.getInstance();
  final isLoggedIn = prefs.getBool('isLoggedIn') ?? false;
  
  if (isLoggedIn) {
    try {
      // 静默登录验证会话是否有效
      final GoogleSignInAccount? account = await GoogleSignIn().signInSilently();
      if (account != null) {
        // 用真实账户信息更新Controller状态
        controller.googleAccount.value = account;
      } else {
        // 会话过期,清除本地存储并跳转登录页
        await prefs.clear();
        Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => LoginPage()));
      }
    } catch (e) {
      // 登录异常,清除无效状态并跳转
      await prefs.clear();
      Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => LoginPage()));
    }
  } else {
    // 未登录状态,直接跳转登录页
    Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => LoginPage()));
  }
}

3. 保证本地存储与真实会话的一致性

如果静默登录成功,对比本地存储的账户信息与真实账户信息,不一致时更新本地存储:

if (account != null) {
  final storedAccountJson = prefs.getString('google_account');
  if (storedAccountJson != null) {
    final storedAccount = jsonDecode(storedAccountJson);
    if (storedAccount['id'] != account.id) {
      // 账户信息变更,更新本地存储
      final newAccountData = {
        'id': account.id,
        'displayName': account.displayName,
        'email': account.email,
        'photoUrl': account.photoUrl,
      };
      await prefs.setString('google_account', jsonEncode(newAccountData));
    }
  }
  controller.googleAccount.value = account;
}

4. 登出时同步清除所有相关数据

登出操作要同时清除本地存储的状态、账户信息,并调用Google官方登出方法:

Future<void> logout() async {
  await GoogleSignIn().signOut();
  final prefs = await SharedPreferences.getInstance();
  await prefs.remove('isLoggedIn');
  await prefs.remove('google_account');
  controller.googleAccount.value = null;
  // 跳转回登录页
  Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => LoginPage()));
}

关键注意点

  • 不要仅依赖本地存储的isLoggedIn判断登录状态,必须结合signInSilently验证会话有效性,避免本地状态与实际登录状态脱节。
  • 本地存储的账户信息仅作为 fallback,优先使用signInSilently返回的真实账户数据。
  • 务必处理signInSilently的异常情况(如用户取消授权、网络故障等),及时清除本地无效状态。

内容的提问来源于stack exchange,提问作者Tyrone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 19:22:46