はじめに
AACのViewModelを用いた場合、onActivityResultが絡んだコードを書くときに辛みが発生していましたが、前回の記事を基に、Firebase AuthでのGoogleログインの処理を書いてみたら思いの外スッキリしたので記録を残しておきます。
なお、本記事ではFirebase Auth×Googleログインに関する基本的な解説はしません。
全体のソースコードはこちらです:https://github.com/masaibar/SimpleGoogleLogin
実装
詳細な差分はこちらを御覧ください。
app/build.gradle
安定版である1.1.0にはActivityResultContract
が含まれていないので注意して下さい。
implementation "androidx.activity:activity-ktx:1.2.0-alpha06"
// implementation "androidx.fragment:fragment-ktx:1.3.0-alpha06" Fragmentの場合
MainActivity.kt
ログインに関する処理を全てViewModel側に閉じ込めることが出来るようになり、Activity側にonActivityResult
を書かなくて良くなったのでボタンのリスナーを呼び出すだけになりました。
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
が参照できないので気をつけましょう。
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