30
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FlutterでFirebaseAuthのエラーハンドリング

Posted at

#背景
FlutterでFirebaseAuthを使ってログインやアカウント作成をするときに、パスワードの間違いメールアドレスの間違いなどユーザーにエラー内容を通知したいのですが、FlutterのFirebaseAuthのエラーコードがわからなかったので、僕がやっているエラーハンドリングの方法をまとめておきます。

iOSは↓これみたいなのですが、Flutterはどうしたら良いのか、、、
Firebase iOS Auth エラーの処理
もし知っている方いれば教えて下さい!笑

#FirebaseAuthから発生する例外をenumに定義

まずはFirebaseAuthからの処理結果をenumに定義します。
きっと他にたくさんあると思いますが、よく使いそうなエラー状態を列挙しています。

enum FirebaseAuthResultStatus {
  Successful,
  EmailAlreadyExists,
  WrongPassword,
  InvalidEmail,
  UserNotFound,
  UserDisabled,
  OperationNotAllowed,
  TooManyRequests,
  Undefined,
}

#FirebaseAuthExceptionクラス

FlutterでFirebaseAuthの例外はFirebaseAuthExceptionクラスで渡されます。

FirebaseAuthExceptionの中身はこのようになっていました。
メールアドレスなどのユーザー情報も渡されるみたいなので、必要であれば適宜使っていきます。

firebase_auth_exception.dart
class FirebaseAuthException extends FirebaseException implements Exception {
  @protected
  FirebaseAuthException(
      {@required this.message,
      this.code,
      this.email,
      this.credential,
      this.phoneNumber,
      this.tenantId})
      : super(plugin: 'firebase_auth', message: message, code: code);

  /// Unique error code
  final String code;

  /// Complete error message.
  final String message;

  /// The email of the user's account used for sign-in/linking.
  final String email;

  /// The [AuthCredential] that can be used to resolve the error.
  final AuthCredential credential;

  /// The phone number of the user's account used for sign-in/linking.
  final String phoneNumber;

  /// The tenant ID being used for sign-in/linking.
  final String tenantId;
}

#FirebaseAuthのエラーコードを取得

FirebaseAuthExceptionで渡されたエラーをcodeを元に、先程enumで宣言した型を返す関数を作成します。

あとでFirebaseAuthのエラーハンドリング用ののclassを作って使うのでstaticにしておきます。

static FirebaseAuthResultStatus handleException(FirebaseAuthException e) {
  FirebaseAuthResultStatus result;
  switch (e.code) {
    case 'invalid-email':
      result = FirebaseAuthResultStatus.InvalidEmail;
      break;

    case 'wrong-password':
      result = FirebaseAuthResultStatus.WrongPassword;
      break;

    case 'user-not-found':
      result = FirebaseAuthResultStatus.UserNotFound;
      break;

    case 'user-disabled':
      result = FirebaseAuthResultStatus.UserDisabled;
      break;

    case 'too-many-requests':
      result = FirebaseAuthResultStatus.TooManyRequests;
      break;

    case 'operation-not-allowed':
      result = FirebaseAuthResultStatus.OperationNotAllowed;
      break;

    case 'email-already-in-use':
      result = FirebaseAuthResultStatus.EmailAlreadyExists;
      break;

    default:
      result = FirebaseAuthResultStatus.Undefined;
      break;
  }
  return result;
}

#エラーメッセージを作成

FirebaseAuthResultStatusによって、エラーメッセージを返す関数を作成しておきます。
このエラーメッセージをshowDialogなどでユーザーに通知するので、好きなように書き換えて使ってください。

static String exceptionMessage(FirebaseAuthResultStatus result) {
  String message = '';
  switch (result) {
    case FirebaseAuthResultStatus.InvalidEmail:
      message = 'メールアドレスが間違っています。';
      break;

    case FirebaseAuthResultStatus.WrongPassword:
      message = 'パスワードが間違っています。';
      break;

    case FirebaseAuthResultStatus.UserNotFound:
      message = 'このアカウントは存在しません。';
      break;

    case FirebaseAuthResultStatus.UserDisabled:
      message = 'このメールアドレスは無効になっています。';
      break;

    case FirebaseAuthResultStatus.TooManyRequests:
      message = '回線が混雑しています。もう一度試してみてください。';
      break;

    case FirebaseAuthResultStatus.OperationNotAllowed:
      message = 'メールアドレスとパスワードでのログインは有効になっていません。';
      break;

    case FirebaseAuthResultStatus.EmailAlreadyExists:
      message = 'このメールアドレスはすでに登録されています。';
      break;

    default:
      message = '予期せぬエラーが発生しました。';
      break;
  }
  return message;
}

#FirebaseAuthの例外を扱うHandlerクラスを作成

上で作ったstatic関数をHandlerクラスに入れます。

class FirebaseAuthExceptionHandler {

  // 上で作った関数
  static FirebaseAuthResultStatus handleException(FirebaseAuthException e) {}

  // 上で作った関数
  static String exceptionMessage(FirebaseAuthResultsStatus result) {}
}

#ログインのロジック部分の関数

今回は例としてログイン時の処理で使い方を書いていきます。

emailとpasswordを引数でFirebaseAuthResultStatusを返す関数を作成します。

Future<FirebaseAuthResultStatus> signIn({String email, String password}) async {
  FirebaseAuthResultStatus result;
  try {
    final UserCredential userCredential = await FirebaseAuth.instance
        .signInWithEmailAndPassword(email: email, password: password);

    if (userCredential.user == null) {
      // ユーザーが取得できなかったとき
      result = FirebaseAuthResultStatus.Undefined;
    } else {
      // ログイン成功時
      result = FirebaseAuthResultStatus.Successful;
    }
  } catch (error) {
    // エラー時
    result = FirebaseAuthExceptionHandler.handleException(error);
  }
  return result;
}

#ログイン処理の実装

ログイン処理の実装です。
先程作ったsignIn関数の戻り値でログインの成功、失敗を判別します。
失敗時にエラーメッセージを取得して、何かでユーザーに通知しましょう。
今回は_showErrorDialogでダイアログ表示をするようにしました。

void login() async {
  final FirebaseAuthResultStatus result = await signIn(
    email: _email,
    password: _password,
  )

  if (result == FirebaseAuthResultStatus.Successful {
    // ログイン成功時の処理
  } else {
    // ログイン失敗時の処理
    final errorMessage = FirebaseAuthExceptionHandler.exceptionMessage(result);
    
    // エラー情報をユーザーに何かで通知
    _showErrorDialog(context, errorMessage);
  }
}

#エラーダイアログの作成

ただエラーメッセージを表示してOKボタンでpopするだけのエラーダイアログ関数です。

void _showErrorDialog(BuildContext context, String message){
  showDialog(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext dialogContext) {
      return AlertDialog(
        title: Text(message),
        actions: <Widget>[
          FlatButton(
            child: Text('OK'),
            onPressed: () {
              Navigator.pop(dialogContext);
            },
          ),
        ],
      );
    },
  );
}

#参考にした記事

基本的にこの記事を参考に書いたのですが、エラーコードが変わっている(?)っぽいので、そこだけ修正しました。
Firebase Auth Exceptions handling | Flutter

#さいごに

もしFlutter×Firebaseを最近やり始めてエラーハンドリングの仕方に迷ってる人がいれば、参考にしてください!
もっと良い方法やアドバイスなどあれば教えて下さい!

30
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?