Firebase Authentication を使った Flutter アプリを開発している。ログインプロバイダーが増減したときのイベントを取得したい。
たとえば、ユーザーアカウントに Apple アカウントが接続されている時には「Appleアカウントと連携中!」と表示し、接続解除時には「Appleアカウントと未接続!」と表示したい。
認証プロバイダーの増減を監視する
よく紹介されている authStateChanges()
を監視する方法ではうまく動かなかった。昔のバージョンではイベントが発火していたのかもしれないが、現行のバージョンでは linkWithProvider()
や unlink()
を呼んでもイベントは発火しなかった。
ログインプロバイダーの増減を監視するためには userChanges()
を使う必要があった。
final authProvider = Provider((ref) => FirebaseAuth.instance); final userChangesProvider = StreamProvider.autoDispose((ref) { var auth = ref.watch(authProvider); return auth.userChanges(); }); class MyApp extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final userChanges = ref.watch(userChangesProvider); return MaterialApp( home: Scaffold( body: /* 省略 */, ); } }
userChanges()
の存在を知らなかったので遠回りになってしまったが、どのデータが変更されたときにどの Stream が流れるのかについては、以下のドキュメントに明記されている。
表にまとめた。
authStateChanges() | idTokenChanges() | userChanges() | |
---|---|---|---|
対応イベント | ・リスナーの登録直後 ・ユーザーがログインしたとき ・現在のユーザーがログアウトしたとき |
・リスナーの登録直後 ・ユーザーがログインしたとき ・現在のユーザーがログアウトしたとき ・現在のユーザーのトークンが変更されたとき |
・リスナーの登録直後 ・ユーザーがログインしたとき ・現在のユーザーがログアウトしたとき ・現在のユーザーのトークンが変更されたとき ・FirebaseAuth.instance.currentUser が提供する次のメソッドが呼び出されたとき: ・reload() ・unlink() ・updateEmail() ・updatePassword() ・updatePhoneNumber() ・updateProfile() |
だめなケース
Widget が rebuild されない。
final authProvider = Provider((ref) => FirebaseAuth.instance); final authStateChangesProvider = StreamProvider.autoDispose((ref) { var auth = ref.watch(authProvider); return auth.authStateChanges(); }); class MyApp extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final authStateChanges = ref.watch(authStateChangesProvider); return MaterialApp( home: Scaffold( body: /* 省略 */, ); } }