📘

Firebaseの電話番号認証をFlutterで実装する方法

2024/01/15に公開

はじめに

前回、WebでのSMSによる電話番号認証を使った方法を説明しましたが、今回は、Flutterでの電話番号認証の実装について説明します。

目次

  • Firebaseの設定
  • 電話番号認証を行う
  • 確認コードの入力
  • 再送処理

Firebaseへ設定追加

FirebaseにFlutterの設定を追加します。cliで自動設定もできますが、Firebaseの設定画面上でAndroidとiOSでそれぞれ設定します。

Android

Firebaseの管理画面でAndroidの登録に必要な各項目を入力し、Androidで利用できるようにします。

  • Androidパッケージ名
  • アプリ名
  • アプリの署名証明書のSHA-1ハッシュ

登録すると、google-services.jsonをダウンロードできるので、<プロジェクトのディレクトリ>/android/src/main/ へ保存してください。

また、手順に従って、Firebaseの依存関係のモジュールをGradleファイル(<プロジェクトのディレクトリ>/android/src/build.gradle)に追加します。

iOS

Firebaseの管理画面でiOSの登録に必要な各項目を入力し、iOSで利用できるようにします。

  • Apple バンドルID
  • アプリ名
  • App Store ID

登録すると、GoogleService-Info.plistをダウンロードできるので、<プロジェクトのディレクトリ>/ios/ へ保存してください。

次に、Xcodeでアプリのプロジェクト(``<プロジェクトのディレクトリ>/ios/Runner.xcworkspace`)を開き、プッシュ通知を有効にします。

プッシュ通知を有効にする

iOSではサイレント APNs 通知と reCAPTCHA 検証を有効にする必要があります。

APNs 認証キーをFirebase Cloud Messagingに登録します。証明書をApple Developerの管理画面で作成し、登録したキーを設定してください。

また、 reCAPTCHA 検証を使用できるようにカスタムURLスキームを登録します。Xcodeでアプリのプロジェクト(``<プロジェクトのディレクトリ>/ios/Runner.xcworkspace`)を開いて、ビルド対象のアプリを選択し、InfoタブにあるURL TypesにアプリIDを登録します。アプリIDは、Firebaseの設定から確認できます。

Firebase認証用にパッケージを追加する

pubspec.yamlに認証に必要なパッケージを追加します。また、Podの更新も必要になるので、iosのディレクトリで pod install を実行してください。

flutter pub add firebase_auth

電話番号認証を行う

電話番号認証をするには、verifyPhoneNumberを利用します。Webと違い、引数には電話番号に以外に、コールバック関数を定義します。verifyPhoneNumber自体は非同期ですが、送った結果については、それぞれコールバックで返ってくるので、コールバックの戻り値を見て、処理を書いていきます。

await FirebaseAuth.instance.verifyPhoneNumber(
    phoneNumber: phoneNumber,
    verificationCompleted: (credential) async {
    },
    verificationFailed: (e) {
    },
    codeSent: (id, resendToken) {
    },
    codeAutoRetrievalTimeout: (id) {
    },
    forceResendingToken: null,
);

codeSent

SMSに成功した場合に、認証コードを一緒に送信するidと再送用のresendTokenが返されます。どちらも後処理で必要になるので、保存してください。

String verificationId = '';
String resendTokenString = '';

await FirebaseAuth.instance.verifyPhoneNumber(
    phoneNumber: phoneNumber,
    codeSent: (id, resendToken) {
        verificationId = id;
        resendTokenString = resendToken?.toString() ?? '';
    },
);

codeAutoRetrievalTimeout

Androidで、SMSで送信されたコードのの自動承認処理が失敗して、タイムアウトになった場合に呼び出されます。これは設定しなくても問題ありません。

verificationFailed

電話番号が間違っていた場合などのFirebaseのエラーが返された場合に、呼び出されます。これが呼び出された場合に、エラー表示をして、再送信や入力を戻す必要があります。

Androidの場合 (verificationCompleted)

Androidの自動認証が有効になっている場合には、コードを入力しなくても、verificationCompletedのコールバックが呼び出されて、Credentialを返してくれます。このオブジェクトを利用すると、ログイン状態にできます。
verificationCompletedはcodeSentの後に呼び出される場合があるので、コードの入力画面で待ちつつ、自動遷移に移るようにします。

await FirebaseAuth.instance.verifyPhoneNumber(
    phoneNumber: phoneNumber,
    verificationCompleted: (credential) async {
        final user = userCredential.user;
          if (user != null) {
          }
    },
);

確認コードの入力

アプリ上で確認コードを入力した後にverifyPhoneNumberで返されたidを使って、認証が正しいか検証します。PhoneAuthProvider.credentialにidと認証コードを設定して、認証情報を作成し、signInWithCredentialを呼び出します。成功すると、ユーザーの認証情報が返されます。

PhoneAuthCredential credential = PhoneAuthProvider.credential(
    verificationId: verificationId,
    smsCode: smsCode,
);

final userCredential =
    await FirebaseAuth.instance.signInWithCredential(credential);

再送処理

同じ電話番号へSMSの再送処理を行うには、verifyPhoneNumberで返されたresendTokenをforceResendingTokenに指定して、もう一度verifyPhoneNumberを呼び出すと、再度SMSが送信されます。

String verificationId = '';
String resendTokenString = '';

await FirebaseAuth.instance.verifyPhoneNumber(
    phoneNumber: phoneNumber,
    codeSent: (id, resendToken) {
        verificationId = id;
        resendTokenString = resendToken?.toString() ?? '';
    },
    forceResendingToken: resendTokenString, // 保存したresendTokenを再利用
);

おわりに

  • 今回はFlutterとFirebaseを用いた電話番号認証についてまとめてみました。みなさんもぜひ試してみてください。
  • センキャクでは一緒にプロダクト開発をしてくれる仲間を絶賛募集しています。少しでもご興味ある方はこちらから。
センキャク Tech Blog

Discussion