Auto RouteでFirebaseAuthを使う
またやってみたけど
前回中と半端な方法で、auto_routeの認証機能を実装してみた。しかし、なんだか満足できなくて、またやってみた。この方法も良いものか???
とりあえずやってみる
前回と同じパッケージを追加して、コードを書いてアプリをビルドします。
📄ページを作成
ログイン後のページを作成します。ログアウトボタンを押すと、ログアウトした後に、画面遷移のコードが実行されます。
ログイン後のページ
import 'package:auto_router/route/router.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:auto_route/auto_route.dart';
()
class HomePage extends StatefulWidget {
const HomePage({super.key});
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () async {
await FirebaseAuth.instance.signOut();
// ログアウトしたら、ログインページへリダイレクト
if (context.mounted) {
context.router.replace(LoginRoute(onResult: (success) {
return;
}));
}
},
child: const Text('ログインページへ'),
),
],
),
),
);
}
}
ログインページを作成します。ルートの定義でこのページを最初に表示する設定にします。
ログインページ
import 'package:auto_router/route/router.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:auto_route/auto_route.dart';
()
class LoginPage extends StatefulWidget {
const LoginPage({super.key});
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
void initState() {
checkAuthState();
super.initState();
}
// ログイン状態をauthStateChangesで、listenして確認
void checkAuthState() {
FirebaseAuth.instance.authStateChanges().listen((User? user) {
if (user != null) {
context.router.replace(const HomeRoute());
}
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Login'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
FirebaseAuth.instance.signInAnonymously();
},
child: const Text('登録しないで利用'),
),
],
),
),
);
}
}
ルートの定義は、router.dart
で行います。ルートを定義したら、ファイルを自動生成するコマンドを実行してください。
flutter pub run build_runner watch --delete-conflicting-outputs
ルートの定義ファイル
import 'package:auto_route/auto_route.dart';
import 'package:auto_router/page/home_page.dart';
import 'package:auto_router/page/login_page.dart';
import 'package:firebase_auth/firebase_auth.dart';
part 'router.gr.dart';
class AuthGuard extends AutoRouteGuard {
void onNavigation(NavigationResolver resolver, StackRouter router) {
// FirebaseAuthのログイン状態を確認
final isAuth = FirebaseAuth.instance.currentUser != null;
// ログイン状態なら、trueを返す
if(isAuth){
resolver.next(true);
}else{
// ログイン状態でなければ、ログインページへリダイレクト
resolver.redirect(LoginRoute(onResult: (success){
resolver.next(success);
}));
}
}
}
()
class AppRouter extends _$AppRouter {
List<AutoRoute> get routes => [
AutoRoute(page: LoginRoute.page, initial: true),
AutoRoute(page: HomeRoute.page, guards: [AuthGuard()]),
];
}
auto_routeをFlutterで使用できるように、MaterialAppの設定を行います。
アプリを実行するファイル
import 'package:auto_router/firebase_options.dart';
import 'package:auto_router/route/router.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
// AppRouterクラスをインスタンス化
AppRouter appRouter = AppRouter();
return MaterialApp.router(
// MaterialApp.routerを使用
routerConfig: appRouter.config(),
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
);
}
}
画面遷移のスクリーンショット
アプリをビルドした時は、認証が通っているかチェックします。
これが、ログインページでボタンを押すと、匿名認証で、HomePageへ行きますが、認証が通っていなかったら、AuthGuard
を使って、HomePageへの画面遷移を防ぐことができます。
ログインできると、このページが表示されます。
ログアウトすると、Login Pageへ遷移します。Login Pageへ戻ってくると認証が通っているかチエックが行われます。
最後に
やってみて、感じたことは認証状態でログイン後のページへリダイレクトするのと、ログアウトするときに、画面遷移のコードを書く必要がありました。
go routerだと、リダイレクトの機能を実装すると、アプリをビルドしたときに、authStateChangesで監視されている状態と組み合わせて、表示するページを切り替えることができます。
しかし、auto routeだと、画面遷移のコードを書く必要がありました。
まだまだ、違和感のあるコードしか書けません???
またやってみたいと思ったのは、サイバーエージェントの勉強会に参加したことがきっかけでした。
イベント情報はこちら
Discussion