April 30, 2022

Flutter Firebase AuthでUserがnullになる

Firebase Auth を使って認証を実装しているのですが、 リリースしているアプリのログを見ると少なくない数でcurrentUserがnullになる現象が起きていました。

FirebaseAuth.instance.currentUser;

認証周りはFirebaseに依存させていて、currentUserがnullになると再認証をしなければならないためユーザビリティが下がってしまっていました。
検証端末でも再現できれば修正しやすいのですが、手元ではうまく再現できずに困っていました。

Firebaseのドキュメント にはご丁寧にcurrentUserがnullになる場合について書かれています。


The currentUser can be null for two reasons:

  • The user isn’t signed in.
  • The auth object has not finished initializing. If you use a listener to keep track of the user’s sign-in status, you don’t need to handle this case.

1つ目はログインしていないので当然nullになります。 2つ目の説明を読むと初期化されていない場合にもnullになると書かれています。

Flutter Firebaseでは initializeApp() を呼び出して初期化するのですがこの初期化とAuthの初期化は別物です。

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
}

ではどうするのかというと、authStateChange のlistenerを監視してから起動するようにします。
ドキュメントにはこのように書かれています。

When the app starts, an event fires after the user credentials (if any) from local storage have been restored, meaning that your listeners always get called when the user state is initialized. Then, whenever the authentication state changes, a new event will be raised with the updated user state. By listening to the authentication state, you can build a user interface that reacts to these changes in authentication state.

起動時にローカルストレージからクレデンシャルの値を取ってきているのでこの値を取得するまで待つ必要があります。

FirebaseAuth.instance
  .authStateChanges()
  .listen((User? user) {
    if (user != null) {
      // launch app
    } else {
      // launch login page
    }
  });

起動時はコールバックのUserの有無でそのまま通常の画面を起動するのかログインページに飛ばすのか判断すると良いと思います。

© AAkira 2021