はじめに
Flutterを利用したアプリ開発をやっている中で
個人的に詰まった部分を定期的に記事にしていこうと思います。
今回実装すること
FirebaseのFirebaseAuthを利用して,
再起動してもログイン状態を保持する機能の実装
#実装
今回はProvider
を利用してログイン状態をアプリを立ち上げた後にどこでも使用できるようにUserState
に保持しておく
→initState
でProviderを使う時は宣言時にlisten:false
を追加し、状態を監視できないようにする(初期状態で監視する必要がないため?エラーを吐くのかもしれない)
Firebaseではユーザの認証状態を自動的に保持し,再起動時に復元してくれているので、FirebaseAuth.instance.currentUser
で現在ログインされているユーザの状態を取得し、
その状態によって後は遷移を書くことで実装することができた。
ログインチェック部分
final currentUser = await FirebaseAuth.instance.currentUser();
final userState = Provider.of<UserState>(context,listen: false);
if(currentUser == null){
Navigator.pushReplacementNamed(context,"/login");
}else{
userState.setUser(currentUser);
Navigator.pushReplacementNamed(context, "/home");
}
main.dart
import 'dart:math';
import 'package:card_manager/page_manager.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:provider/provider.dart';
import 'login_page.dart';
void main() {
runApp(MyApp());
}
class UserState extends ChangeNotifier{
FirebaseUser user;
void setUser(FirebaseUser currentUser){
user = currentUser;
notifyListeners();
}
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
final UserState user = UserState();
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<UserState>.value(
value: user,
child: MaterialApp(
//デバックラベル非表示
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: LoginCheck(),
initialRoute: "/",
routes:<String, WidgetBuilder>{
AddRecord.routeName: (BuildContext context) => AddRecord(),
"/login":(BuildContext context) => LoginPage(),
"/home":(BuildContext context) => PageManager(),
},
)
);
}
}
class LoginCheck extends StatefulWidget{
LoginCheck({Key key}) : super(key: key);
@override
_LoginCheckState createState() => _LoginCheckState();
}
class _LoginCheckState extends State<LoginCheck>{
//ログイン状態のチェック(非同期で行う)
void checkUser() async{
final currentUser = await FirebaseAuth.instance.currentUser();
final userState = Provider.of<UserState>(context,listen: false);
if(currentUser == null){
Navigator.pushReplacementNamed(context,"/login");
}else{
userState.setUser(currentUser);
Navigator.pushReplacementNamed(context, "/home");
}
}
@override
void initState(){
super.initState();
checkUser();
}
//ログイン状態のチェック時はこの画面が表示される
//チェック終了後にホーム or ログインページに遷移する
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: Text("Loading..."),
),
),
);
}
}
最後に
- ログイン状態が自動的に保持されるFirebaseは便利だと思った反面、正しく理解していないと不具合が起きた際に対処できないと思った。
- 結局、自分も実装してみて
currentUser
で再起動後も保持されていることを知ったので、公式の解説がどこにあるかはわかっていない(知っている方がいたらコメントで教えてくださると助かります!)