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

GoRouter始终仅显示登录页,各类导航操作无效问题求助

问题:Flutter应用导航始终停留在登录页,重定向与authState监听未触发

我的应用无论执行何种导航操作(如设置初始路由至其他页面、context.push、context.go等),始终仅显示登录页面。我在认证系统中实现了重定向函数,未认证时会跳转回登录页,但这似乎不是问题根源——点击导航按钮时,两个打印语句"authState changes"和"Redirect!"均未触发。

提供的代码

main.dart

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:sneaker_app/models/cart.dart';
import 'package:sneaker_app/routes/app_route_config.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:sneaker_app/services/auth_service.dart';
import 'firebase_options.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  // Referesh GoRouter configuration every time authState changes (Authentication guaranteed)
  FirebaseAuth.instance.authStateChanges().listen((User? user) {

    print("authState changes");

    MyAppRouter.router.refresh();
  });

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
        providers: [
          ChangeNotifierProvider<Cart>(create: (context) => Cart()),
          ChangeNotifierProvider<AuthService>(
              create: (context) => AuthService())
        ],
        child: MaterialApp.router(
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
              colorScheme: ColorScheme.fromSeed(seedColor: Colors.grey)),
          routerConfig: MyAppRouter.router,
        ));
  }
}

路由配置文件(app_route_config.dart)

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:sneaker_app/models/shopee_tile.dart';
import 'package:sneaker_app/pages/home_page.dart';
import 'package:sneaker_app/pages/item_page.dart';
import 'package:sneaker_app/pages/login_page.dart';
import 'package:sneaker_app/pages/signup_page.dart';
import 'package:sneaker_app/routes/app_route_constants.dart';
import 'package:sneaker_app/services/auth_service.dart';

class MyAppRouter {
  static final GoRouter router = GoRouter(
    initialLocation: "/login",
    routes: [
      GoRoute(
          name: MyAppRouteConstants.homeRouteName,
          path: "/",
          builder: (context, state) => HomePage()),
      GoRoute(
          name: MyAppRouteConstants.itemRouteName,
          path: "/item/:id",
          builder: (context, state) {
            ShopeeTile item = state.extra as ShopeeTile;
            return ItemPage(
              id: int.parse(state.pathParameters["id"]!),
              item: item,
            );
          }),
      GoRoute(
          name: MyAppRouteConstants.loginRouteName,
          path: "/login",
          builder: (context, state) => LoginPage()),
      GoRoute(
          name: MyAppRouteConstants.signupRouteName,
          path: "/signup",
          builder: (context, state) => SignupPage()),
    ],
    redirect: (BuildContext context, GoRouterState state) async {
      final bool loggedIn =
          Provider.of<AuthService>(context, listen: false).user != null;
      final bool loggingIn = state.matchedLocation == "/login";

      print("Redirect!");

      if (!loggedIn) return "/login";
      if (loggingIn) return "/";
      // no need to redirect at all
      return null;
    },
  );
}

登录页按钮代码

TextButton(
              child: Text('Sign up'),
              onPressed: () {
                context.pushNamed(MyAppRouteConstants.signupRouteName);
              },
            ),

问题分析与解决方案

核心问题总结

  1. GoRouter的redirect回调被错误标记为异步,导致逻辑执行异常
  2. 重定向逻辑未允许未登录用户访问注册页,强制跳转回登录页
  3. FirebaseAuth的状态变化未同步到AuthService,导致重定向逻辑一直判定为未登录
  4. GoRouter未监听AuthService的状态变化,无法自动触发重定向更新

修改后的代码

1. 更新AuthService(添加状态同步方法)

class AuthService extends ChangeNotifier {
  User? _user;
  User? get user => _user;

  // 用于同步FirebaseAuth的用户状态
  void setUser(User? newUser) {
    _user = newUser;
    notifyListeners();
  }
}

2. 修改路由配置文件

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:sneaker_app/models/shopee_tile.dart';
import 'package:sneaker_app/pages/home_page.dart';
import 'package:sneaker_app/pages/item_page.dart';
import 'package:sneaker_app/pages/login_page.dart';
import 'package:sneaker_app/pages/signup_page.dart';
import 'package:sneaker_app/routes/app_route_constants.dart';
import 'package:sneaker_app/services/auth_service.dart';

class MyAppRouter {
  static final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

  // 改为接收AuthService实例,实现状态监听
  static GoRouter router(AuthService authService) {
    return GoRouter(
      navigatorKey: navigatorKey,
      // 根据当前用户状态动态设置初始路由
      initialLocation: authService.user != null ? "/" : "/login",
      routes: [
        GoRoute(
            name: MyAppRouteConstants.homeRouteName,
            path: "/",
            builder: (context, state) => HomePage()),
        GoRoute(
            name: MyAppRouteConstants.itemRouteName,
            path: "/item/:id",
            builder: (context, state) {
              ShopeeTile item = state.extra as ShopeeTile;
              return ItemPage(
                id: int.parse(state.pathParameters["id"]!),
                item: item,
              );
            }),
        GoRoute(
            name: MyAppRouteConstants.loginRouteName,
            path: "/login",
            builder: (context, state) => LoginPage()),
        GoRoute(
            name: MyAppRouteConstants.signupRouteName,
            path: "/signup",
            builder: (context, state) => SignupPage()),
      ],
      // 移除async修饰符,修正重定向逻辑
      redirect: (BuildContext context, GoRouterState state) {
        final bool loggedIn = authService.user != null;
        final bool loggingIn = state.matchedLocation == "/login";
        final bool signingUp = state.matchedLocation == "/signup";

        print("Redirect!");

        // 未登录时允许访问登录、注册页,其他页面跳转登录
        if (!loggedIn) {
          if (loggingIn || signingUp) return null;
          return "/login";
        }
        // 已登录时在登录页则跳转首页
        if (loggingIn) return "/";
        return null;
      },
      // 监听AuthService状态变化,自动触发重定向
      refreshListenable: authService,
    );
  }
}

3. 修改main.dart

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:sneaker_app/models/cart.dart';
import 'package:sneaker_app/routes/app_route_config.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:sneaker_app/services/auth_service.dart';
import 'firebase_options.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<Cart>(create: (context) => Cart()),
        ChangeNotifierProvider<AuthService>(create: (context) => AuthService())
      ],
      // 通过Consumer获取AuthService实例,绑定路由与状态
      child: Consumer<AuthService>(
        builder: (context, authService, child) {
          // 同步FirebaseAuth状态到AuthService
          FirebaseAuth.instance.authStateChanges().listen((User? user) {
            print("authState changes");
            authService.setUser(user);
          });

          return MaterialApp.router(
            debugShowCheckedModeBanner: false,
            theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.grey)),
            routerConfig: MyAppRouter.router(authService),
          );
        },
      ),
    );
  }
}

验证修改效果

  1. 点击登录页的"Sign up"按钮,可正常跳转到注册页,"Redirect!"打印语句会触发
  2. 用户登录后,authStateChanges会触发,"authState changes"打印语句输出,同时自动跳转到首页
  3. 未登录时访问首页会被重定向到登录页;已登录时访问登录页会被重定向到首页

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 03:27:05