🔥

【Flutter×FirebaseAuth】email認証が完了したら画面遷移する方法

2021/11/07に公開

はじめに

最近した業務でFirebaseAuthのEmail認証が完了したタイミングで画面遷移をする必要があり方法がわからなくて困ったため私と同じように困っている方のために残しておきたいと思います。

なぜFirebaseAuthのauthStateChangesを使わなかったのか

authStateChangesを使わない理由

  • トリガーが発火する条件が以下にあり、メール認証をしたかどうかをリアルタイムに検知できないため
    FlutterFireより引用

Events are fired when the following occurs:
・ Right after the listener has been registered.
・ When a user is signed in.
・ When the current user is signed out.

結論

  • FirebaseAuthのcurrentUserに用意されているreload関数を毎秒実行することで解決しました。

執筆時の環境

  • Flutter2.5.2
  • flutter_riverpodを使用

前提

  • Flutter web
  • Firebaseの設定が完了していること。
  • FirebaseAuthのsendEmailVerificationメソッドが実行されていてメール認証が未完了であること。

実装方法

View

dart(最初の画面)
class SamplePage extends ConsumerWidget {
  const SamplePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, ScopedReader watch) {
    final model = watch(sendEmailModelProvider);
// emailVerifiedがtrueへ変わったらSampleSecondPageへ遷移
    if (model.emailVerified == true) {
      return const SampleSecondPage();
    }
    return const Scaffold(
      body: Center(
        child: Text('最初の画面'),
      ),
    );
  }
}

ViewModel

毎秒実行している処理をtimer.cancel()で止めないと遷移後も遷移前の最初の画面で実行し続けてしまうため、今回はemailVerifiedtrueになったらcancelしています。

dart
final sampleModelProvider =
    ChangeNotifierProvider((_) => SampleModel()..timerReading());

class SampleModel extends ChangeNotifier {
  bool emailVerified = false;

  // 毎秒reload関数を実行してAuthのemailVerifiedの状態を監視している
  void timerReading() {
    Timer.periodic(const Duration(seconds: 1), (Timer timer) async {
      await FirebaseAuth.instance.currentUser!.reload();
      emailVerified = FirebaseAuth.instance.currentUser!.emailVerified;
// emailVerifiedがtrueに変更されたタイミングで毎秒処理を止めています。
      if (emailVerified == true) {
        timer.cancel();
      }
      notifyListeners();
    });
  }
}


参考にしたサイト

FlutterFire
Timer.periodic constructor

Discussion