🤩
[Flutter]SharedPreferencesを用いたログイン保持の方法(備忘録)
はじめに
アプリを作成している時にログイン機能を作成しました!
しかし、毎回ログインするためのデータを入力するのは面倒で困ってました...
そこでアプリに必要不可欠と言っても過言ではないログイン保持機能を実装を備忘録として残しておきます。
参考にしたもの
今回はJBoyさんの「Flutterでログイン後の状態を維持する」の記事を参考にさせていただきました。
開発環境
Flutterバージョン
Flutter 3.13.7 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 2f708eb839 (4 weeks ago) • 2023-10-09 09:58:08 -0500
Engine • revision a794cf2681
Tools • Dart 3.1.3 • DevTools 2.25.0
パッケージバージョン
shared_preferences: ^2.0.15
実装コード
最初に今回利用するコードを記載しておきます。
今回は、FirebaseAuthを利用した匿名ログインユーザーのログイン保持機能を実装します。
(本記事はログイン保持のロジックのみ)
PreferencesManager
SharedPreferencesの機能を利用している部分をPreferencesManagerにまとめて利用していきます。
class PreferencesManager {
factory PreferencesManager() {
return _incessance;
}
PreferencesManager._internal();
static late final SharedPreferences _preferences;
static final PreferencesManager _incessance = PreferencesManager._internal();
Future<void> set(SharedPreferences preferences) async =>
_preferences = preferences;
Future<bool> get isLogin async {
return _preferences.getBool(_isLogin) ?? false;
}
Future<void> setIsLogin({
required bool isLogin,
}) async {
await _preferences.setBool(_isLogin, isLogin);
}
}
setIsLoginを使用する場面
ログインした際にチェックしたいのでonPressedの中にそのまま記載します。
ElevatedButton(
child: const Text('サインインせずに利用'),
onPressed: () async {
await PreferencesManager().setIsLogin(isLogin: true);
context.go(Routes.main);
},
);
get isLoginを使用する場面
isLoginの値をProviderで管理しています。
class SplashPageState with _$SplashPageState {
const factory SplashPageState({
bool? isLogin,
}) = _SplashPageState;
}
final splashPageProvider =
StateNotifierProvider.autoDispose<SplashPageController, SplashPageState>(
(ref) {
return SplashPageController();
});
class SplashPageController extends StateNotifier<SplashPageState> {
SplashPageController() : super(const SplashPageState()) {
init();
}
Future<void> init() async {
if (_isAuthenticated && mounted) {
final isLogin = await PreferencesManager().isLogin;
state = state.copyWith(isLogin: isLogin);
}
}
}
SplashPage.dartの中身
isLoginの値によって画面遷移先を設定します。
Consumer(
builder: (context) {
ref.listen<bool?>(splashPageProvider.select((s) => s.isLogin),
(_, isLogin) async {
if (isLogin == false) {
context.go(Routes.signin);
}else{
context.go(Routes.main);
}
});
return Scaffold(
body: Center(
child: Container(
child: const Text('Loading...'),
),
),
);
},
);
注意事項
下記の部分を追記しないとPreferencesManagerのDart_preferences
が利用できないので注意
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: getFirebaseOptions());
//ここを記載しないとPreferencesManagerの_preferencesが利用できないので注意
await PreferencesManager().set(await SharedPreferences.getInstance());
runApp(const ProviderScope(child: MyApp()));
}
利用した感想
ローカルで値を保持することができるSharedPreferencesはすごい!
今までチーム開発で利用されているのは知っていたが利用方法はあまり理解できてなかった...
再度個人で利用するとより理解度が深まりますね
DartdocId
を保存しログインしたユーザーのデータを取得するなどの利用方法もできそうです
より理解するために
より深く理解されたい方はこちらの方の記事が詳しく説明してあってわかりやすいので参考にされてください。
Discussion
FirebaseAuthenticationを使うなら、authStateChangeを使えばログイン状態を維持できるので、
SharedPreferences
は必要ないそうです。以前はつかわれていたようですが?バックエンドのAPIを使ったJWT認証のような、Webトークンなるものを保存する目的で、こちらの方法を使うのが一般的だそうです。
以前は、こんな記事なかったので、良い内容だとは思いますね。