使用 refreshlistener 实现 Go Router 和 Bloc 的身份验证

Implementation Auth with Go Router and Bloc using refreshlistener

提问人:Chan May Lan 提问时间:10/23/2023 更新时间:10/23/2023 访问量:36

问:

即使身份验证状态已通过身份验证,也无法重定向到主屏幕

首先,我创建了一个身份验证通知器

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:tedtris_app/bloc/auth_bloc.dart';
import 'package:tedtris_app/locator.dart';

class AuthStreamScope extends InheritedNotifier<AuthStream> {
  AuthStreamScope({super.key, required super.child})
      : super(notifier: AuthStream(locator.get<AuthBloc>().stream));
  static AuthStream of(BuildContext ctx) =>
      ctx.dependOnInheritedWidgetOfExactType<AuthStreamScope>()!.notifier!;
}

class AuthStream extends ChangeNotifier {
  late final StreamSubscription<dynamic> _subscription;

  AuthStream(Stream<dynamic> stream) {
    _subscription = stream.listen((_) => notifyListeners());
  }

  AuthStatus isSignedIn() => locator.get<AuthBloc>().state.authStatus;

  @override
  void dispose() {
    _subscription.cancel();
    super.dispose();
  }
}

其次,我包装 AuthStreamScope 并读取身份验证状态更改

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:path_provider/path_provider.dart';
import 'package:tedtris_app/bloc/auth_bloc.dart';
import 'package:tedtris_app/bloc/auth_notifier.dart';
import 'package:tedtris_app/locator.dart';
import 'package:tedtris_app/repository/auth_repository.dart';
import 'package:tedtris_app/screens/auth/home_screen.dart';
import 'package:tedtris_app/screens/auth/login_screen.dart';
import 'package:tedtris_app/theme/light_theme.dart';

// // GoRouter Configuration
final _router = GoRouter(
  routes: [
    GoRoute(
        path: "/",
        redirect: (context, state) {
          var result = AuthStreamScope.of(context).isSignedIn();
          return "/login";
        },
        routes: [
          GoRoute(
            path: "login",
            builder: (context, state) {
              return BlocProvider<AuthBloc>(
                lazy: false,
                create: (context) => AuthBloc(authRepository: AuthRepository())
                  ..add(AuthStarted()),
                child: const LoginScreen(),
              );
            },
          )
        ]),
    GoRoute(
        path: "/home",
        builder: (context, state) {
          return const Scaffold(
            body: HomeScreen(),
          );
        }),
  ],
);

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Init GetIt
  Setup();

  // Init Hydrated Bloc Storage
  HydratedBloc.storage = await HydratedStorage.build(
    storageDirectory: kIsWeb
        ? HydratedStorage.webStorageDirectory
        : await getTemporaryDirectory(),
  );
  runApp(const TedtrisApp());
}

class TedtrisApp extends StatefulWidget {
  const TedtrisApp({super.key});

  @override
  State<TedtrisApp> createState() => _TedtrisAppState();
}

class _TedtrisAppState extends State<TedtrisApp> {
  @override
  Widget build(BuildContext context) {
    return AuthStreamScope(
        child: MaterialApp.router(
      debugShowCheckedModeBanner: false,
      routerConfig: _router,
      theme: lightTheme,
    ));
  }
}

第三,使用 GetIt 将 bloc 注入为 DI

import 'package:get_it/get_it.dart';
import 'package:tedtris_app/bloc/auth_bloc.dart';
import 'package:tedtris_app/repository/auth_repository.dart';

final locator = GetIt.I;

void Setup() {
  locator
      .registerLazySingleton(() => AuthBloc(authRepository: AuthRepository()));
}

但是最后,即使我触发了该事件,函数重定向也不会重新呈现

颤振 集团 flutter-bloc

评论


答: 暂无答案