Android-Access Google Sign In

1. Login category

Authorized login and one-click login.
One-click login will fail to log in on some devices, and a whitelist error will be reported. Most foreign applications use authorized login, and it is recommended to use authorized login

2. Apply for a key

Creating an Android project directly in FireBase will directly generate related keys in Google Cloud, and there is no need to manually create them in Google Cloud.
An Android and a Web configuration will be generated, and a Web Key is required.

3. Authorized login

class LoginActivity : BaseActivity() {
    
    
    companion object {
    
    
        private const val SIGN_LOGIN = 901

        /**
         * google自动登录,使用的是Web的key。web项目会在Android项目生成的时候自动生成
         */
        private const val SERVER_CLIENT_ID = "xxx"
    }
    
    private lateinit var auth: FirebaseAuth
    private var mGoogleSignInClient: GoogleSignInClient? = null

    private fun signInClient() {
    
    
        if (mGoogleSignInClient == null) {
    
    
            val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .requestIdToken(SERVER_CLIENT_ID)
                .build();
            mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
        }
    }


    private fun getGoogleIntent(): Intent {
    
    
        var signInInten: Intent
        if (mGoogleSignInClient == null) {
    
    
            signInClient();
        }
        signInInten = mGoogleSignInClient!!.signInIntent;
        return signInInten
    }

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        ...
        auth = FirebaseAuth.getInstance()
        btnLoginGoogle.setOnClickListener {
    
    
                signInClient()
                startActivityForResult(getGoogleIntent(), SIGN_LOGIN)
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    
    
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
    
    
            SIGN_LOGIN -> {
    
    
                val task = GoogleSignIn.getSignedInAccountFromIntent(data);
                if (task == null) {
    
    
                    Log.d("tag", "task:null")
                }
                try {
    
    
                    val account = task.getResult(ApiException::class.java)
                    Log.d("tag", "id:" + account.idToken)
                    val firebaseCredential = GoogleAuthProvider.getCredential(account.idToken, null)
                    auth.signInWithCredential(firebaseCredential)
                        .addOnCompleteListener(this@LoginActivity) {
    
     task ->
                            if (task.isSuccessful) {
    
    
                                // Sign in success, update UI with the signed-in user's information
                                Log.d("tag", "signInWithCredential:success")
                                val user = auth.currentUser
                                user?.getIdToken(true)
                                    ?.addOnCompleteListener(OnCompleteListener<GetTokenResult?> {
    
     task ->
                                        if (task.isSuccessful) {
    
    
                                            val idToken: String? = task.result.token
                                           // 和后台交互进行登录
                                        } else {
    
    
                                            // Handle error -> task.getException();
                                        }
                                    })
                            } else {
    
    
                                // If sign in fails, display a message to the user.
                                Log.w("tag", "signInWithCredential:failure", task.exception)
                            }
                        }
                } catch (e: ApiException) {
    
    
                    Log.d("tag", "task:" + e.localizedMessage)
                }
            }
        }
    }
}

4. One-click login

    private val REQ_ONE_TAP = 2  // Can be any integer unique to the Activity
    private lateinit var oneTapClient: SignInClient
    private lateinit var signInRequest: BeginSignInRequest


        oneTapClient = Identity.getSignInClient(this)
        signInRequest = BeginSignInRequest.builder()
            .setPasswordRequestOptions(BeginSignInRequest.PasswordRequestOptions.builder().setSupported(true).build())
            .setGoogleIdTokenRequestOptions(
                BeginSignInRequest.GoogleIdTokenRequestOptions.builder()
                    .setSupported(true)
                    .setServerClientId(ServerClientId)
                    .setFilterByAuthorizedAccounts(false)
                    .build()
            ).setAutoSelectEnabled(true).build()

//https://developers.google.com/identity/one-tap/android/get-saved-credentials
                oneTapClient.beginSignIn(signInRequest)
                    .addOnSuccessListener(this@LoginActivity) {
    
     result ->
                        try {
    
    
                            startIntentSenderForResult(
                                result.pendingIntent.intentSender, REQ_ONE_TAP,
                                null, 0, 0, 0, null
                            )
                        } catch (e: IntentSender.SendIntentException) {
    
    
                            Log.e("tag", "Couldn't start One Tap UI: ${
      
      e.localizedMessage}")
                        }
                    }
                    .addOnFailureListener(this@LoginActivity) {
    
     e ->
                        // No saved credentials found. Launch the One Tap sign-up flow, or
                        // do nothing and continue presenting the signed-out UI.
                        Log.d("tag", e.localizedMessage)
                     
                    }

onActivityResult

REQ_ONE_TAP -> {
    
    
                try {
    
    
                    val credential = oneTapClient.getSignInCredentialFromIntent(data)
                    val idToken = credential.googleIdToken
                    val username = credential.id
                    val password = credential.password
                    when {
    
    
                        idToken != null -> {
    
    
                            // Got an ID token from Google. Use it to authenticate
                            // with your backend.
                            Log.d("tag", "Got ID token:" + idToken)
                            val firebaseCredential = GoogleAuthProvider.getCredential(idToken, null)
                            auth.signInWithCredential(firebaseCredential)
                                .addOnCompleteListener(this@LoginActivity) {
    
     task ->
                                    if (task.isSuccessful) {
    
    
                                        // Sign in success, update UI with the signed-in user's information
                                        Log.d("tag", "signInWithCredential:success")
                                        val user = auth.currentUser
                                        user?.getIdToken(true)
                                            ?.addOnCompleteListener(OnCompleteListener<GetTokenResult?> {
    
     task ->
                                                if (task.isSuccessful) {
    
    
                                                    val idToken: String? = task.result.token
                                                    Log.d("tag", "uid: " + user.uid)
                                                    Log.d("tag", "IDToken: " + idToken)
                                                } else {
    
    
                                                    // Handle error -> task.getException();
                                                }
                                            })
                                    } else {
    
    
                                        // If sign in fails, display a message to the user.
                                        Log.w("tag", "signInWithCredential:failure", task.exception)
                                     
                                    }
                                }
                        }
                        password != null -> {
    
    
                            // Got a saved username and password. Use them to authenticate
                            // with your backend.
                            Log.d("tag", "Got password.")
                        }
                        else -> {
    
    
                            // Shouldn't happen.
                            Log.d("tag", "No ID token or password!")
                        }
                    }
                } catch (e: ApiException) {
    
    
                    // ...
                }
            }

5. Common Mistakes

It is possible that the error is a problem with the VPN, check your own network

5.1 Failure16:Cannot find a matching credential.

In one-click login scenario: the login mode is changed to register and log in

5.2 Failure10:Caller not whitelisted to call this API

The test account has not joined Google Cloud

5.3 12500

Check whether the signatures of debug and release are configured to firebase

5.4 Firebase ID token has incorrect “aud” (audience) claim.

The background verification failed. After obtaining the idToken, you need to use the API of GoogleAuthProvider for secondary processing

5.5 Firebase Installations Service is unavailable.

For network problems, you need to see the error message in the console, and it will not be displayed in the login callback. Connect to external network
com.google.firebase.installations.FirebaseInstallationsException: Firebase Installations Service is unavailable. Please try again later.

material

❤️Android Google Login Access ❤️

Guess you like

Origin blog.csdn.net/Android_yh/article/details/129352068