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

登录后再次登录,注销功能失效需重启应用问题求助

Flutter跨平台应用注销失效问题排查与修复

问题现象

开发Android/iOS跨平台应用时,首次登录后注销功能正常,但再次登录后,注销功能完全失效,必须重启应用才能恢复正常。

现有注销代码

注销按钮点击事件

ListTile(
  leading: Icon(
    Iconsax.logout,
    color: Colors.red,
  ),
  title: Text(
    'logout'.tr,
    style: TextStyle(color: Colors.red),
  ),
  onTap: () {
    Geofire.removeLocation(currentFirebaseUser!.uid);
    rideRequestRef!.onDisconnect();
    rideRequestRef!.remove();
    rideRequestRef = null;
    loggOut(context);
  },
)

核心注销方法

void loggOut(BuildContext context) {
    showDialog(
        context: context,
        barrierDismissible: true,
        builder: (BuildContext context) {
          return ProgressDialog(message: 'logging_out'.tr);
        });

    FirebaseAuth.instance.signOut();
    GoogleSignIn().signOut();

    Future.delayed(Duration(seconds: 2), () {
      Navigator.pushNamedAndRemoveUntil(
          context, BeforeLogin.idScreen, (route) => false);
      displayToast('loggedout_success'.tr, context);
    });
}

问题根源分析

  1. Firebase引用未正确重置/更新:再次登录后,currentFirebaseUser和rideRequestRef可能未重新赋值,导致注销时空断言(!)抛出异常,后续操作中断。
  2. GoogleSignIn实例未复用:每次注销都创建新的GoogleSignIn()实例,无法匹配当前登录会话,导致signOut操作无效。
  3. onDisconnect操作错误:rideRequestRef!.onDisconnect()仅注册断开监听,未绑定具体移除动作,无法确保断开时清理数据。
  4. 异步操作未同步:未等待Firebase、Google登录的注销操作完成就执行导航,导致状态未同步,UI残留旧状态。

修复方案

1. 复用GoogleSignIn实例

在全局或状态类中初始化实例,避免每次注销创建新对象:

// 类顶部或全局定义
final GoogleSignIn _googleSignIn = GoogleSignIn();

// 注销方法中使用复用的实例
void loggOut(BuildContext context) {
    // ... 其他代码
    FirebaseAuth.instance.signOut();
    _googleSignIn.signOut();
    // ... 其他代码
}

2. 完善Firebase引用清理逻辑

添加空值判断,避免空断言异常,同时修正onDisconnect操作:

onTap: () async {
  if (currentFirebaseUser != null) {
    await Geofire.removeLocation(currentFirebaseUser!.uid);
  }
  if (rideRequestRef != null) {
    await rideRequestRef!.onDisconnect().remove();
    await rideRequestRef!.remove();
    rideRequestRef = null;
  }
  loggOut(context);
},

3. 等待异步操作完成后再导航

取消固定延迟,等待所有注销操作完成后执行导航:

void loggOut(BuildContext context) async {
    showDialog(
        context: context,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return ProgressDialog(message: 'logging_out'.tr);
        });

    await FirebaseAuth.instance.signOut();
    await _googleSignIn.signOut();

    Navigator.pop(context);
    Navigator.pushNamedAndRemoveUntil(
        context, BeforeLogin.idScreen, (route) => false);
    displayToast('loggedout_success'.tr, context);
}

4. 登录时重置全局状态

登录成功后重新初始化用户和请求引用,避免使用旧数据:

void onLoginSuccess(User user) {
  currentFirebaseUser = user;
  rideRequestRef = FirebaseDatabase.instance.ref().child('rideRequests').child(user.uid);
  // 其他初始化逻辑
}

额外建议

  • 避免使用空断言(!),改用空安全的条件判断(?.或if != null),防止运行时异常中断功能。
  • 借助状态管理工具(如Provider、Bloc)管理用户登录状态,确保注销/登录时状态同步。

内容的提问来源于stack exchange,提问作者Ankit Kumar Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 03:48:42