我制作了一个web应用程序,并将其部署到firebase。假设链接是https://firebasewebapp
。当我打开链接时,会显示Sign In
表单,但当我打开https://firebasewebapp/#/home
时,即使用户没有登录,我也会重定向到home page
。如果用户不是logged in
,有没有方法重定向用户?我使用Flutter 2.10.3 Stable Channel
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: options),
);
runApp(MultiProvider(providers: [
], child: const MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Portalul e-Radauti',
theme: ThemeData(
primarySwatch: Colors.orange,
textButtonTheme: TextButtonThemeData(
style: ButtonStyle(
backgroundColor:
MaterialStateColor.resolveWith((states) => Colors.orange),
foregroundColor:
MaterialStateColor.resolveWith((states) => Colors.white),
),
),
),
initialRoute: '/login',
routes: {
'/home': (_) => const MyHomePage(),
'/addcouncilmember': (_) => const LocalCouncilLayout(),
'/signup': (_) => const SignUp(),
'/login': (_) => const LogIn(),
'/addevent': (_) => const AddEventLayout(),
'/profile': (_) => const Profile(),
},
// home: const MyApp(),
);
}
}
最简单的方法是使用Flutter的Navigator 2.0或包装Navigator 2.0的API的软件包,如go_router或beamer。
以下是如何使用go_router:实现此行为的示例
省道
import 'package:go_router/go_router.dart';
import 'app.dart';
import 'redirection/log_in.dart';
import 'redirection/my_home_page.dart';
import 'redirection/sign_up.dart';
GoRouter routerGenerator(LoggedInStateInfo loggedInState) {
return GoRouter(
initialLocation: Routes.login,
refreshListenable: loggedInState,
redirect: (state) {
final isOnLogin = state.location == Routes.login;
final isOnSignUp = state.location == Routes.signup;
final isLoggedIn = loggedInState.isLoggedIn;
if (!isOnLogin && !isOnSignUp && !isLoggedIn) return Routes.login;
if ((isOnLogin || isOnSignUp) && isLoggedIn) return Routes.home;
return null;
},
routes: [
GoRoute(
path: Routes.home,
builder: (_, __) => const MyHomePage(),
),
GoRoute(
path: Routes.login,
builder: (_, __) => LogIn(loggedInState),
),
GoRoute(
path: Routes.signup,
builder: (_, __) => SignUp(loggedInState),
),
],
);
}
abstract class Routes {
static const home = '/home';
static const signup = '/signup';
static const login = '/login';
}
app.dart
import 'package:flutter/material.dart';
import 'router.dart';
class LoggedInStateInfo extends ChangeNotifier {
bool _isLoggedIn = false;
bool get isLoggedIn => _isLoggedIn;
void login() {
_isLoggedIn = true;
notifyListeners();
}
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _loggedInStateInfo = LoggedInStateInfo();
late final _router = routerGenerator(_loggedInStateInfo);
@override
void dispose() {
_loggedInStateInfo.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp.router(
debugShowCheckedModeBanner: false,
routeInformationParser: _router.routeInformationParser,
routerDelegate: _router.routerDelegate,
);
}
}
使用此代码,您只需要更新LoggedInStateInfo
中_isLoggedIn
的值,并通知侦听器访问HomePage
,否则即使手动更改URL,您也只能访问LogIn
和SignUp
页面。
奖金
LogIn
页代码
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import '../app.dart';
import '../router.dart';
class LogIn extends StatelessWidget {
final LoggedInStateInfo loggedInStateInfo;
const LogIn(this.loggedInStateInfo, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('LogIn')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
onPressed: loggedInStateInfo.login,
child: const Text('Log In'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () => context.push(Routes.signup),
child: const Text('Sign Up'),
),
],
),
),
);
}
}
SignUp
页代码
import 'package:flutter/material.dart';
import '../app.dart';
class SignUp extends StatelessWidget {
final LoggedInStateInfo loggedInStateInfo;
const SignUp(this.loggedInStateInfo, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('SignUp')),
body: Center(
child: ElevatedButton(
onPressed: loggedInStateInfo.login,
child: const Text('Sign Up'),
),
),
);
}
}