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

Flutter中pushReplacement调用后返回键仍打开原页面问题

问题原因分析
  1. 导航栈未彻底清空:pushReplacement仅替换当前页面,之前的首页仍留存于导航栈中,导致按下返回键可回到首页。
  2. 登录状态清除不彻底:代码仅调用FirebaseAuth.instance.signOut(),未处理GoogleSignIn的登出逻辑,可能导致Auth状态未及时更新。
  3. SplashScreen逻辑缺陷:
    • 依赖固定延迟的Timer跳转,未实时监听Auth状态变化,可能在登出后仍读取到旧用户状态。
    • 当用户未验证邮箱时,同时触发跳转到EmailVerification和3秒后强制跳转到HomeScreen的逻辑,造成导航冲突。
解决方案

1. 修复登出函数

  • 同时清除GoogleSignIn与FirebaseAuth的登录状态,确保登出操作彻底。
  • 使用pushAndRemoveUntil清空导航栈,仅保留目标页面,避免返回键回到历史页面。

修改后的登出代码:

void signOut(context) async {
  final googleCurrentUser = FirebaseAuth.instance.currentUser;
  if (googleCurrentUser != null) {
    // 先清除Google登录状态
    await GoogleSignIn().signOut();
    // 再清除Firebase Auth状态
    await FirebaseAuth.instance.signOut();
    
    // 清空导航栈并跳转至SplashScreen
    if(mounted) {
      Navigator.of(context).pushAndRemoveUntil(
        PageRouteBuilder(
          pageBuilder: (_, __, ___) => const SplashScreen(),
          transitionDuration: const Duration(milliseconds: 500),
          transitionsBuilder: (_, a, __, c) => FadeTransition(
            opacity: a,
            child: c,
          ),
        ),
        (route) => false, // 清除所有之前的页面
      );
    }
  }
}

2. 重构SplashScreen逻辑

  • 移除Timer,改用authStateChanges监听用户登录状态,实时响应状态变化。
  • 优化导航逻辑,避免重复跳转操作。

修改后的SplashScreen代码:

import 'dart:async';
import 'package:app/screens/email_verification.dart';
import 'package:app/screens/home_screen.dart';
import 'package:app/screens/sign_in.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';

class SplashScreen extends StatefulWidget {
  const SplashScreen({super.key});

  @override
  State<StatefulWidget> createState() => SplashScreenState();
}

class SplashScreenState extends State<SplashScreen> {
  StreamSubscription<User?>? _authSubscription;

  @override
  void initState() {
    super.initState();
    WidgetsFlutterBinding.ensureInitialized();
    _listenToAuthState();
  }

  @override
  void dispose() {
    _authSubscription?.cancel();
    super.dispose();
  }

  void _listenToAuthState() {
    _authSubscription = FirebaseAuth.instance.authStateChanges().listen((user) {
      if (user != null) {
        debugPrint("Current User - ${user.uid}");
        // 检查邮箱验证状态
        if (!user.emailVerified) {
          _navigateTo(const EmailVerification());
        } else {
          _navigateTo(const HomeScreen());
        }
      } else {
        // 用户已登出,跳转至登录页
        _navigateTo(const SignIn());
      }
    });
  }

  void _navigateTo(Widget page) {
    if(mounted) {
      Navigator.of(context).pushAndRemoveUntil(
        PageRouteBuilder(
          pageBuilder: (_, __, ___) => page,
          transitionDuration: const Duration(milliseconds: 500),
          transitionsBuilder: (_, a, __, c) => FadeTransition(
            opacity: a,
            child: c,
          ),
        ),
        (route) => false,
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Image.asset(
          'assets/images/logo.gif',
          gaplessPlayback: false,
          repeat: ImageRepeat.noRepeat,
        ),
      ),
    );
  }
}

关键说明

  • pushAndRemoveUntil配合(route) => false会清空整个导航栈,新页面成为栈中唯一页面,按下返回键将直接退出应用,不会回到之前的页面。
  • authStateChanges能实时监听用户登录状态变化,确保SplashScreen总能获取最新的Auth状态,避免因状态延迟导致的错误跳转。
  • 同时清除GoogleSignIn和FirebaseAuth状态,保证登出操作彻底,避免残留登录信息导致的状态异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:13:17