Firebase Authenticationの実装(Android, Google認証)

Firebase Authenticationの実装を行ったので実装内容をまとめておきます。

この記事では以下の内容についてまとめています。

  • Android
  • Kotlinで実装
  • Googleアカウントを用いた認証

基本的には公式ドキュメント(https://firebase.google.com/docs/auth/android/google-signin)の内容通りの実装です。

Googleログインの統合まわりで別のページ(https://developers.google.com/identity/sign-in/android/sign-in)を案内されるのが少し分かりにくかったので自分用にまとめ直しています。
(ちょっとガーっと書いちゃったのであとで見直します。見直すべき。見直したい人生だった。)

build.gradleへの追記内容

Firebase Authentication用のモジュールとGoogle Sign-In用のモジュール(Google Play Service)が必要となるので 以下のようになります。

apply plugin: 'com.google.gms.google-services'

android {
    …
}

dependencies {
    // Google Sign-In
    implementation 'com.google.android.gms:play-services-auth:16.0.0'

    // Firebase Authentication
    implementation 'com.google.firebase:firebase-core:16.0.3'
    implementation 'com.google.firebase:firebase-auth:16.0.3'

Firebaseのプロジェクト側での設定とgoogle-services.jsonの生成

こちらは公式ドキュメントの「準備」に手順が書いてあるので詳しくはそちらを参照してください。 Firebase Consoleにアクセスし、対象となるFirebaseプロジェクト(なければ新規作成する)にAndroidアプリを追加(パッケージ名の登録や、key storeのフィンガープリントの登録が必要)を行うとgoogle-service.jsonファイルがダウンロード可能になるので、そちらをアプリに配置します。

現在の認証状況を確認する

通常アプリで認証を要求する前に、現在の認証状況を確認し、認証済みの場合は通常時の処理、未認証の場合はログイン画面などへの遷移を行うかと思います。 Firebase Authenticationを用いて認証状況を確認する場合はFirebaseAuthオブジェクトのcurrentUserプロパティを取得する事で、現在認証済みの状態であるか判断できます。 currentUserプロパティはFirebaseUserクラスのインスタンスとなっており、ユーザー名などの情報を取得することも可能です。

なお、こちらはFirebase Authenticationの状態が認証状態にあるか否かを確認するため、Googleアカウントによる認証かどうかは問いません。

val firebaseAuth = FirebaseAuth.getInstance()

if (firebaseAuth.currentUser != null) {
    // 認証済み
} else {
    // 未認証
}

Google Sign-Inを要求する

Googleアカウントを用いてFirebase Authenticationを行う場合

  1. Google Sign-Inを使用してGoogleアカウントの認証を行い、Credentialを取得する
  2. 取得したCredentialをFirebaseに送信し、Firebase Authenticationを行う。

となります。その為のGoogle Sign-In要求のコードは以下のようなものになります。
(R.string.default_web_client_idgoogle-services.jsonの配置とbuild.gradleの記述が間違っていなければ自動生成されているはずです)

val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(getString(R.string.default_web_client_id))
                .requestEmail()
                .build()

val googleSignInClient = GoogleSignIn.getClient(this, gso)

startActivityForResult(googleSignInClient.signInIntent, RC_SIGN_IN)

Google Sign-In結果の取得

Google Sign-Inの結果はActivityResult()を通じて取得できます。 取得したGoogle Sign-Inの結果を用いてFirebaseAuth. signInWithCredential()の呼び出しを行うことで、Firebase Authenticationに対してGoogleアカウントでの認証を要求します。

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (requestCode == RC_SIGN_IN && data != null) {
        try {
            // Google Sign In was successful, authenticate with Firebase
            val account = GoogleSignIn.getSignedInAccountFromIntent(data)
                .getResult(ApiException::class.java)
            
            val credential = GoogleAuthProvider.getCredential(account.idToken, null)

            firebaseAuth.signInWithCredential(credential)
                .addOnCompleteListener(this) { task ->
                if (task.isSuccessful) {
                    // TODO Firebase Authentication成功時の処理
                } else {
                    // TODO Firebase Authentication失敗の処理
                }
            }
        } catch (e: ApiException) {
            // TODO Google Sign-In失敗時の処理
        }
    } else {
        super.onActivityResult(requestCode, resultCode, data)
    }
}