酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Flutterで、Firebase Authentication の認証プロバイダーの増減を監視する

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 が流れるのかについては、以下のドキュメントに明記されている。

firebase.google.com

表にまとめた。

  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: /* 省略 */,
    );
  }
}