#この記事で紹介すること
FirebaseのAuthenticationを用いてGoogleログイン/ユーザー登録を実現する方法を紹介します。
プロジェクト(アプリ)をFirebaseに登録していることが前提です。
まだできていない方は公式ドキュメント|AndroidプロジェクトにFirebaseを追加するを参考に、まずはアプリの登録から行ってください。
またこの記事は私がアプリを作る中でドキュメントを参考にしてコードを書き、ドキュメント通りにいかなかった部分もあったため、あえて記事としてまとめています。参考にした公式ドキュメントは以下です。Android で Firebase Authentication を使ってみる
#Firebase Authenticationを使ってGoogleアカウントでログイン/ユーザー登録ができるようにしよう!
まずは、Firebase Authenticationがあなたのアプリで使えるように、app/build.gradle
に以下を追加します。
dependencies {
implementation platform('com.google.firebase:firebase-bom:26.2.0')
implementation 'com.google.firebase:firebase-auth-ktx'
}
firebase-bom:
の後ろは最新のバージョンを公式ドキュメントで確認して入力してください(Android で Firebase Authentication を使ってみるの「アプリにFirebase Authentication を追加する」のところのコード)。上記はこの記事をかいた時点での最新です。
次に、AuthenticationActivityを作成します。
だいたいこんなかんじです。
※FirebaseAuthと関係ないコードも入ってます
※以下のコードはViewBindingを適用しています
(ViewBindingに関しては別の記事で紹介しています)
※以下のコードはRepositoryを利用してFirestoreへアクセスしています
(Repositoryに関しては別で書いているMVVMの記事を参考にして下さい)
class AuthenticationActivity : AppCompatActivity() {
private var googleSignInClient: GoogleSignInClient? = null
private val repository = UserInfoRepository()
private val RC_GOOGLE_SIGN_IN_CODE = 9001
// ViewBindingの設定
private lateinit var binding: ActivityAuthenticationBinding
private lateinit var auth: FirebaseAuth
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ViewBindingの設定
binding = ActivityAuthenticationBinding.inflate(layoutInflater)
.apply { setContentView(this.root) }
var gso = GoogleSignInOptions
.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build()
googleSignInClient = GoogleSignIn.getClient(this, gso)
// lateinit var authの初期化
auth = Firebase.auth
binding.googleAccountLinkButton.setOnClickListener {
googleSignIn()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == RC_GOOGLE_SIGN_IN_CODE) {
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
try {
val account = task.getResult(ApiException::class.java)!!
firebaseAuthWithGoogle(account.idToken!!)
} catch (e: Exception) {
Log.w("TAG", "Google sign in failed", e)
}
}
}
private fun googleSignIn() {
var googleSignInIntent = googleSignInClient?.signInIntent
startActivityForResult(googleSignInIntent, RC_GOOGLE_SIGN_IN_CODE)
}
// Google認証(Googleアカウントを選択する画面)から戻ってきた後のプログラムはここに書く
// 以下は、ログインなのか新規ユーザー登録をすべきなのか判定して、それぞれにあった画面遷移をするようなプログラムになっている
private fun firebaseAuthWithGoogle(idToken: String) {
val credential = GoogleAuthProvider.getCredential(idToken, null)
auth.signInWithCredential(credential)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
// 現在このアプリを開いているユーザのuidを取得
val uid = auth.currentUser!!.uid
Log.d("TAG", uid)
// 取得したuidと一致するuidがFirestoreのユーザー情報を登録しているコレクションに存在するか検索する
var result: List<SaveUserInfo>
GlobalScope.launch {
// 引数のuidと一致するuidのデータを取得
result = repository.getUser(uid)
Log.d("TAG", result.toString())
if (result.isNullOrEmpty()) {
// データを取得できなかった場合(初回ログイン)
// 新規ユーザー登録画面へ移動
val intent = Intent(
this@AuthenticationActivity,
RegisterUserInfoActivity::class.java
)
intent.putExtra("UID", uid)
startActivity(intent)
} else {
// データを取得できた場合(2回目以降ログイン)
// ログインした後一番最初に表示したい画面に移動
val intent =
Intent(this@AuthenticationActivity, CountPageActivity::class.java)
startActivity(intent)
}
}
}
}
}
}
ちなみに、Repositoryは以下のようになってます。
#Repository
class UserInfoRepository {
// 引数のuidと一致するユーザー情報を取得
suspend fun getUser(uid: String?): List<SaveUserInfo> {
return suspendCoroutine { cont ->
val db = FirebaseFirestore.getInstance()
val task = db.collection("userInfo")
.whereEqualTo("uid", uid)
.get()
task.addOnCompleteListener {
val resultList = task.result!!.toObjects(SaveUserInfo::class.java)
cont.resume(resultList)
}
}
}
}
上記では、FirestoreのuserInfo
というコレクションの中から引数のuidと一致するデータ(uidやユーザー名等を含んだユーザー情報)を取得しています。
#さいごに
(一番最初に見せるべきだったのかもしれませんが...)
やっていることを漫画チックに表現するとこんな感じです。
逆に分かりにくいかもですが。以上です!!!!