I am in the process of implementing sign-in via the Google account in the Android app. Now I have the known issue of com.google.android.gms.common.api.ApiException: 10 when trying to sign in.
Most StackOverflow answers refer to improper SHA-1 key and advise to match it between local .gradlew signing report, google developers console, and firebase console. I did all of that, removed my SHA-1 and created a new one during the new build, made sure that it matches my local key store, Google Developer Console, and Firebase Console. Also, I hardcoded web_client_id and made sure my package name is the same in Google Developers and Firebase Consoles. Still doesn't work.
So the idea is maybe in within at the app SHA-1 key is not populated properly at the compile time? There is a known similar issue with the web_client_id which we need to hardcode. Web_client_id is populated from the same place where the SHA-1 key is stored: google-services.json file. Could you please help: How can I make sure that my SHA-1 is populated properly? How can I log my SHA-1 key at run time? Are there other ideas to solve this login problem? Below is my code for the sign in fragment class:
package com.exa.myProject.login
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.exa.myProject.R
import com.exa.myProject.list.ListNonRespondedActivity
import com.exa.myProject.unsorted.Global.Companion.TAG
import com.exa.myProject.unsorted.Global.Companion.toastString
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.common.SignInButton
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.tasks.Task
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.auth.GoogleAuthProvider
import com.google.firebase.auth.ktx.auth
import com.google.firebase.ktx.Firebase
private const val RC_SIGN_IN = 100
class GoogleSignInFragment : Fragment(){
lateinit var auth: FirebaseAuth
var googleSignInClient: GoogleSignInClient? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id_hardcoded))
.requestEmail()
.build()
googleSignInClient = this.activity?.let { GoogleSignIn.getClient(it, gso) }
auth = Firebase.auth
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_google_sign_in, container, false)
val signInButton: SignInButton = view.findViewById<View>(R.id.sign_in_button) as SignInButton
signInButton.setOnClickListener {
signIn()
}
signInButton.setSize(SignInButton.SIZE_STANDARD)
return view
}
override fun onStart() {
super.onStart()
val currentUser = auth.currentUser
updateUI(currentUser)
}
private fun signIn() {
val signInIntent = googleSignInClient?.signInIntent
startActivityForResult(signInIntent, RC_SIGN_IN)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == RC_SIGN_IN) {
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
handleSignInResult(task)
}
}
private fun firebaseAuthWithGoogle(idToken: String) {
val credential = GoogleAuthProvider.getCredential(idToken, null)
this.activity?.let {
auth.signInWithCredential(credential)
.addOnCompleteListener(it) { task ->
if (task.isSuccessful) {
Log.i(TAG, "signInWithCredential:success")
val user = auth.currentUser
updateUI(user)
} else {
Log.i(TAG, "signInWithCredential:failure", task.exception)
updateUI(null)
}
}
}
}
private fun updateUI(model: FirebaseUser?){
val signInStatus = if (model == null) getString(R.string.user_not_signed) else
getString(R.string.welcome) + model.displayName
toastString(signInStatus)
if (model != null) {
val intent = Intent(this.activity, ListNonRespondedActivity::class.java)
startActivity(intent)
}
}
private fun handleSignInResult(task: Task<GoogleSignInAccount>) {
try {
val account = task.getResult(ApiException::class.java)!!
Log.d(TAG, "firebaseAuthWithGoogle:" + account.id)
firebaseAuthWithGoogle(account.idToken!!)
} catch (e: ApiException) {
Log.w(TAG, "Google sign in failed", e)
updateUI(null)
}
}
}