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

Flutter中如何通过Go Router导航到Shell Route?

解决方案

你的核心问题在于路由路径冲突(登录页与Shell下的首页共用/),且手动在登录页跳转不符合GoRouter的设计逻辑。用GoRouter自带的redirect功能可以更优雅地实现登录状态的路由切换,具体步骤如下:

1. 修复路由路径冲突

把登录页的路径从/改为/login,避免和Shell下的首页路由匹配冲突:

GoRoute(
  parentNavigatorKey: _rootNavigator,
  path: '/login', // 修改为/login
  name: 'login',
  builder: (context, state) => AppLoginScreen(key: state.pageKey),
),

2. 用redirect处理认证重定向

在GoRouter初始化时添加redirect回调,通过FirebaseAuth判断登录状态,自动跳转对应路由:

GoRouter router = GoRouter(
  navigatorKey: _rootNavigator,
  initialLocation: '/',
  // 核心:认证状态重定向逻辑
  redirect: (context, state) {
    final user = FirebaseAuth.instance.currentUser;
    final isLoggedIn = user != null;
    final isLoginPage = state.location == '/login';

    // 未登录且不在登录页 → 跳登录页
    if (!isLoggedIn && !isLoginPage) return '/login';
    // 已登录且在登录页 → 跳Shell首页
    if (isLoggedIn && isLoginPage) return '/';
    // 其他情况不做重定向
    return null;
  },
  // 其余路由配置保持不变...
);

3. 简化登录页代码

移除登录页里的StreamBuilder跳转逻辑,让redirect自动处理路由切换,登录页只负责展示登录UI:

Scaffold(
  body: Center(
    child: SizedBox(
      width: 400,
      child: ui.SignInScreen(
        providers: [ui.EmailAuthProvider()],
        actions: [
          ui.AuthStateChangeAction<ui.SignedIn>((context, state) {
            // 登录成功后触发路由刷新,让redirect生效
            GoRouter.of(context).go(HomeScreen.routeName);
          }),
        ],
      ),
    ),
  ),
);

额外说明

如果需要实时响应登录状态变更(比如用户退出时自动跳回登录页),可以在App根Widget监听authStateChanges(),状态变化时调用GoRouter.of(context).refresh()触发redirect重新执行:

StreamBuilder(
  stream: FirebaseAuth.instance.authStateChanges(),
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.active) {
      GoRouter.of(context).refresh();
    }
    return MaterialApp.router(routerConfig: router);
  },
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 01:24:30