GoRouter 总是只显示一页

问题描述 投票:0回答:1

问题:无论我进行何种导航(例如将初始位置设置为另一个页面、context.push、context.go 等),我的应用程序始终显示登录屏幕。我在身份验证系统中实现了一个重定向功能,如果用户未经身份验证,则将用户重定向回登录页面,但这似乎不是罪魁祸首(两个打印语句:“authState更改”和“重定向!”没有被调用当我按下导航按钮时)。

我的 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,
        ));
  }
}

我的应用程序路由器配置:

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;
    },
  );
}

我可以确保 MyAppRouteConstants 中的常量与其路径匹配

这是登录页面上的按钮小部件

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

我尝试通过放置打印语句来调试问题,但我无法找出为什么应用程序只停留在登录页面并且根本不导航。

flutter navigation flutter-navigation flutter-go-router gorouter
1个回答
0
投票

根据您提供的代码片段,我的第一个猜测是问题出在以下行:

routerConfig: MyAppRouter.router,

由于您显然具有内置身份验证来决定用户登陆的位置,因此 MyApp 的构建方法将被再次调用。但是,由于这一行,正在创建一个新的 GoRouter 对象,因为您正在为 MyAppRouter 中的路由器分配一个新对象。

作为测试,尝试将 GoRouter 对象作为全局变量存储在 main.dart 文件中:

GoRouter myRouter = GoRouter(...)

现在将此变量作为 routerConfig 传递。这可能已经是解决方案了。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.