问题:无论我进行何种导航(例如将初始位置设置为另一个页面、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);
},
),
我尝试通过放置打印语句来调试问题,但我无法找出为什么应用程序只停留在登录页面并且根本不导航。
根据您提供的代码片段,我的第一个猜测是问题出在以下行:
routerConfig: MyAppRouter.router,
由于您显然具有内置身份验证来决定用户登陆的位置,因此 MyApp 的构建方法将被再次调用。但是,由于这一行,正在创建一个新的 GoRouter 对象,因为您正在为 MyAppRouter 中的路由器分配一个新对象。
作为测试,尝试将 GoRouter 对象作为全局变量存储在 main.dart 文件中:
GoRouter myRouter = GoRouter(...)
现在将此变量作为 routerConfig 传递。这可能已经是解决方案了。