Help us understand the problem. What is going on with this article?

ActivityResultContractとViewModelを使ってFirebase Auth×Googleログインをスッキリ書く

はじめに

AACのViewModelを用いた場合、onActivityResultが絡んだコードを書くときに辛みが発生していましたが、前回の記事を基に、Firebase AuthでのGoogleログインの処理を書いてみたら思いの外スッキリしたので記録を残しておきます。
なお、本記事ではFirebase Auth×Googleログインに関する基本的な解説はしません。

全体のソースコードはこちらです:https://github.com/masaibar/SimpleGoogleLogin

実装

詳細な差分はこちらを御覧ください。

app/build.gradle

安定版である1.1.0にはActivityResultContractが含まれていないので注意して下さい。

app/build.gradle
    implementation "androidx.activity:activity-ktx:1.2.0-alpha06"
//      implementation "androidx.fragment:fragment-ktx:1.3.0-alpha06" Fragmentの場合

MainActivity.kt

ログインに関する処理を全てViewModel側に閉じ込めることが出来るようになり、Activity側にonActivityResultを書かなくて良くなったのでボタンのリスナーを呼び出すだけになりました。

MainActivity.kt
class MainActivity : AppCompatActivity() {

    private val viewModel: MainViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        sign_in_button.setOnClickListener {
            viewModel.onClickSignIn(this)
        }
    }
}

MainViewModel.kt

onClickSignInで受け取るのはFragmentActivity型にしないとactivityResultRegistryが参照できないので気をつけましょう。

MainViewModel.kt
class MainViewModel : ViewModel() {

    private val firebaseAuth: FirebaseAuth = FirebaseAuth.getInstance()

    fun onClickSignIn(activity: FragmentActivity) {
        val googleSignInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(activity.getString(R.string.default_web_client_id))
            .requestEmail()
            .build()
        val googleSignInClient = GoogleSignIn.getClient(
            activity,
            googleSignInOptions
        )

        activity.activityResultRegistry.register(
            "key",
            ActivityResultContracts.StartActivityForResult()
        ) { activityResult ->
            if (activityResult.data == null) {
                return@register
            }

            GoogleSignIn.getSignedInAccountFromIntent(activityResult.data)
                .addOnCompleteListener { task ->
                    if (task.isSuccessful) {
                        task.getResult(ApiException::class.java)?.let {
                            firebaseAuthWithGoogle(it)
                        }
                    }
                }
        }.launch(googleSignInClient.signInIntent)
    }

    private fun firebaseAuthWithGoogle(account: GoogleSignInAccount) {
        firebaseAuth.signInWithCredential(
            GoogleAuthProvider.getCredential(
                account.idToken,
                null
            )
        ).addOnSuccessListener {
            Log.d("Login Succeeded!!!", "${it.user?.uid}")
        }
    }
}

おわりに

ViewModel側にログインにまつわる処理を閉じ込めることが出来たおかげで、UI側をシンプルなコードに保つことが出来るようになりました。
例えばこの記事のように、MVVMとFirebase Authの実装方法は様々な議論がされてきていると思いますがActivityResultContractを利用することによって新たな可能性が生まれたと思います。

全体のソースコードはこちらです(再掲):https://github.com/masaibar/SimpleGoogleLogin

masaibar
globis
グロービスは 1992 年の創業以来、社会人を対象とした MBA、人材育成の領域で Ed-Tech サービスを提供し、現在は日本 No.1 の実績があります。これらの資産と、さらに IT や AI を活用することで、アジア No.1 を目指しています。
http://www.globis.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした