簡體   English   中英

Firebase 使用 Google 進行身份驗證

[英]Firebase Authentication with Google

我正在嘗試在 firebase 中使用 google 設置我的身份驗證。 到目前為止,我設法訪問了 Google 帳戶信息,例如姓名、email 地址和 ID。 現在我想根據這些信息創建一個 firebase 用戶,但不知何故這不能很好地工作。 我逐步瀏覽了 firebase 文檔。 當涉及到“firebaseAuthWithGoogle(account.idToken..)”部分時,我的應用程序崩潰了。 在調試模式下檢查顯示 account.idToken = null。

我希望描述足夠詳細。 非常感謝您的幫助:我正在使用以下依賴項:

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

這是我的代碼:

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 給我以下錯誤:

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) 

所以我終於自己找到了解決方案。 當我在 onCreate 方法中配置 Google 登錄時,我錯過了對 IdToken 的請求......

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM