简体   繁体   中英

Firebase Authentication with Google

I am trying to set up my authentication with google in firebase. So far I managed to get access to the google account information like names, email addresss and ID. Now I would like to create a firebase user from this information but somehow this does not work quite well. I went through the firebase documentation step by step. When it comes to the part of "firebaseAuthWithGoogle(account.idToken..)" my app is crashing. Checking in debug mode shows that account.idToken = null.

I hope the description is detailed enough. Big thanks in advance for help: I am using the following dependencies:

implementation 'com.google.firebase:firebase-auth:19.3.1'
implementation 'com.google.android.gms:play-services-auth:18.0.0'

This is my code:

const val RC_SIGN_IN = 123

class SignUpAcitivity : AppCompatActivity() {

    private lateinit var auth: FirebaseAuth

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sign_up_acitivity)
        auth = FirebaseAuth.getInstance()



        // Configure sign-in to request the user's ID, email address, and basic
        // profile. ID and basic profile are included in DEFAULT_SIGN_IN.
        val gso =
            GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .build()

        // Build a GoogleSignInClient with the options specified by gso.
        val mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
        google_sign_in_button.setSize(SignInButton.SIZE_STANDARD)
        google_sign_in_button.setOnClickListener{
            val signInIntent = mGoogleSignInClient.signInIntent
            startActivityForResult(signInIntent, RC_SIGN_IN)
        }
        val acct = GoogleSignIn.getLastSignedInAccount(this)
        if (acct != null) {
            /*val personName = acct.displayName
            val personGivenName = acct.givenName
            val personFamilyName = acct.familyName
            val personEmail = acct.email
            val personId = acct.id
            val personPhoto: Uri? = acct.photoUrl*/
            Toast.makeText(
                baseContext, "${acct.displayName}",
                Toast.LENGTH_SHORT
            ).show()
        }

        btn_signup2.setOnClickListener{
            signUpUser()
        }
    }

    private fun signUpUser() {
        if (editTextTextEmailAddressSignUp.text.toString().isEmpty()) {
            editTextTextEmailAddressSignUp.error = "Please enter email"
            editTextTextEmailAddressSignUp.requestFocus()
            return
        }
        if(!Patterns.EMAIL_ADDRESS.matcher(editTextTextEmailAddressSignUp.text.toString()).matches()){
            editTextTextEmailAddressSignUp.error = "Please enter valid email"
            editTextTextEmailAddressSignUp.requestFocus()
            return
        }
        if (editTextTextPasswordSignUp.text.toString().isEmpty()) {
            editTextTextPasswordSignUp.error = "Please enter password"
            editTextTextPasswordSignUp.requestFocus()
            return
        }

        auth.createUserWithEmailAndPassword(editTextTextEmailAddressSignUp.text.toString(), editTextTextPasswordSignUp.text.toString())
            .addOnCompleteListener(this) { task ->
                if (task.isSuccessful) {
                    val user = auth.currentUser
                    user?.sendEmailVerification()
                        ?.addOnCompleteListener { task ->
                            if (task.isSuccessful) {
                                //Log.d(TAG, "Email sent.")
                                Toast.makeText(baseContext, "Authentication email sent.", Toast.LENGTH_SHORT).show()
                                startActivity(Intent(this, LoginActivity::class.java))
                                finish()
                            }
                        }
                    startActivity(Intent(this, LoginActivity::class.java))
                    finish()
                } else {
                    // If sign in fails, display a message to the user.
                    //Log.w(TAG, "createUserWithEmail:failure", task.exception)
                    Toast.makeText(baseContext, "Authentication failed. Try again.",
                        Toast.LENGTH_SHORT).show()
                }
            }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        // Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
            // The Task returned from this call is always completed, no need to attach
            // a listener.
            val task =
                GoogleSignIn.getSignedInAccountFromIntent(data)
            handleSignInResult(task)
        }
    }

    private fun handleSignInResult(completedTask: Task<GoogleSignInAccount>) {
        try {
            val account =
                completedTask.getResult(ApiException::class.java)

            // Signed in successfully, show authenticated UI.
            if (account != null) {
                Toast.makeText(
                    baseContext, "${account.displayName}",
                    Toast.LENGTH_SHORT
                ).show()
                val personName = account.displayName
                val personGivenName = account.givenName
                val personFamilyName = account.familyName
                val personEmail = account.email
                val personId = account.id
                val test = account.idToken
                firebaseAuthWithGoogle(account.idToken!!)
            }
        } catch (e: ApiException) {
            // The ApiException status code indicates the detailed failure reason.
            // Please refer to the GoogleSignInStatusCodes class reference for more information.
            Log.w("FragmentActivity.TAG", "signInResult:failed code=" + e.statusCode)
            Toast.makeText(
                baseContext, "Something went wrong.",
                Toast.LENGTH_SHORT
            ).show()
        }
    }

    private fun firebaseAuthWithGoogle(idToken: String) {
        val credential = GoogleAuthProvider.getCredential(idToken, null)
        auth.signInWithCredential(credential)
            .addOnCompleteListener(this) { 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
                    Toast.makeText(baseContext, "Sign-Up successful.", Toast.LENGTH_SHORT).show()
                    startActivity(Intent(this, LoginActivity::class.java))
                    finish()
                } else {
                    // If sign in fails, display a message to the user.
                    //Log.w(TAG, "signInWithCredential:failure", task.exception)
                    // ...
                    Toast.makeText(baseContext, "Authentication failed. Try again.",
                        Toast.LENGTH_SHORT).show()
                }

                // ...
            }
    }
}

Logcat is giving me the following error:

2020-06-29 09:48:36.855 27864-27864/com.developments.testsubscriptions E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.developments.testsubscriptions, PID: 27864
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=123, result=-1, data=Intent { (has extras) }} to activity {com.developments.testsubscriptions/com.developments.testsubscriptions.SignUpAcitivity}: kotlin.KotlinNullPointerException
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5471)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:5512)
        at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2386)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:213)
        at android.app.ActivityThread.main(ActivityThread.java:8178)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
     Caused by: kotlin.KotlinNullPointerException
        at com.developments.testsubscriptions.SignUpAcitivity.handleSignInResult(SignUpAcitivity.kt:139)
        at com.developments.testsubscriptions.SignUpAcitivity.onActivityResult(SignUpAcitivity.kt:118)
        at android.app.Activity.dispatchActivityResult(Activity.java:8413)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5464)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:5512) 
        at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2386) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:213) 
        at android.app.ActivityThread.main(ActivityThread.java:8178) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101) 

So I finally found the solution by myself. When I was configuring Google Sign-In in onCreate method I was missing the request for IdToken....

        val gso =
            GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(getString(R.string.default_web_client_id))
                .requestEmail()
                .build()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM