GoRouter всегда показывает только одну страницу

Проблема: мое приложение всегда отображает экран входа в систему, независимо от того, какой тип навигации я выполняю (например, установка исходного местоположения на другую страницу, 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,
        ));
  }
}

Конфигурации маршрутизатора моего приложения:

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

Я попытался отладить проблему, вставив операторы печати, но не смог понять, почему приложение застряло только на странице входа и вообще не перемещалось.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Учитывая предоставленные вами фрагменты кода, я могу предположить, что проблема заключается в следующей строке:

routerConfig: MyAppRouter.router,

Поскольку у вас, очевидно, есть встроенная аутентификация, позволяющая решить, куда попадает пользователь, метод сборки MyApp вызывается снова. Однако из-за этой строки создается новый объект GoRouter, поскольку вы назначаете новый объект маршрутизатору в MyAppRouter. И эта конфигурация затем принимает LoginPage (/login) в качестве начального местоположения.

В качестве теста попробуйте сохранить объект GoRouter в файле main.dart как глобальную переменную:

GoRouter myRouter = GoRouter(...)

Теперь передайте эту переменную как routerConfig. Возможно, это уже решение.

Теперь у меня есть «Перенаправление!» напечатано на консоли: O, хотя мой статус аутентификации никогда не менялся

khoaoaoaoa 09.07.2024 16:35

Я предполагаю, что перенаправление вызывается каждый раз, когда вы переходите на страницу, даже если это ваша начальная страница. Итак, если вы запускаете свое приложение, вы переходите к /login. Эта навигация должна вызывать вашу логику внутри вашего перенаправления.

Ozan Taskiran 09.07.2024 16:38

Кроме того, у меня есть вопрос. Я помечаю GoRouter myRouter в классе appRouterConfigs как статический и читал в Интернете, что если переменная помечена как статическая, то существует только один «экземпляр» этой переменной, доступный каждому экземпляру. Так почему же, когда метод сборки вызывается несколько раз, а также создается множество новых экземпляров MyAppRouterConfigs, назначаются разные экземпляры «myRouter»? Разве они все не ссылаются на одну и ту же статическую переменную маршрутизатора в этом классе?

khoaoaoaoa 09.07.2024 16:56

Это только один экземпляр. Но каждый раз, когда вы вызываете build, он переходит в строку MyAppRouter.router. Это проверяет, что находится за маршрутизатором. И в вашем случае вы всегда создаете новый экземпляр GoRouter и записываете его в свое статическое поле. Таким образом, каждый раз, когда вы вызываете сборку, вы создаете новый GoRouter, который можно использовать в любом месте вашего проекта. Вы не хотите создавать экземпляр каждый раз, когда вызываете сборку, вам не нужно создавать его только один раз. И этот экземпляр следует использовать в вашем коде, если он вам нужен.

Ozan Taskiran 09.07.2024 17:32

Другие вопросы по теме