0
votes

I need to login users with Google Sign On onto Firebase. But since I need to use the Calendar API, I have to do a custom login (and not the one provided through Firebase on default), as I need the Oauth refresh token - which is not provided by Firebase. I have looked at the docs but none seem to work, I am using the below code as of now... can anybody suggest how do I use the token obtained from Google to login/register with Firebase?

private const val TAG = "WelcomeActivity"

class WelcomeActivity : AppCompatActivity() {

    var firebaseUser: FirebaseUser? = null

    //For Google Sign In
    val RC_SIGN_IN: Int = 9001
    private lateinit var mGoogleSignInClient: GoogleSignInClient
    lateinit var mGoogleSignInOptions: GoogleSignInOptions
    private lateinit var firebaseAuth: FirebaseAuth
    private var firebaseUserID: String = ""
    private lateinit var refUsers: DatabaseReference

    //get data from google signin in handlesigninresult
    private var googleId = ""
    private var googleFirstName = ""
    private var googleLastName = ""
    private var googleEmail = ""
    private var googleProfilePicURL = ""

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_welcome)
    //        //For google sign in
    //        configureGoogleSignIn()
    //        setupUI()
      //      enablePersistence()
            firebaseAuth = FirebaseAuth.getInstance()

    val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestIdToken("")
        .requestEmail()
        .build()
    mGoogleSignInClient = GoogleSignIn.getClient(this, gso)

    google_login.setOnClickListener {
        signIn()
    }

    login_welcome.setOnClickListener {
        val intent = Intent(this@WelcomeActivity, LoginActivity::class.java)
        startActivity(intent)
        finish()
    }
}

private fun signIn() {
    val signInIntent = mGoogleSignInClient.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 handleSignInResult(completedTask: Task<GoogleSignInAccount>) {
    try {
        val account = completedTask.getResult(
            ApiException::class.java
        )
        // Signed in successfully
        googleId = account?.id ?: ""
        Log.i("Google ID", googleId)

        googleFirstName = account.givenName ?: ""
        Log.i("Google First Name", googleFirstName)

        googleLastName = account?.familyName ?: ""
        Log.i("Google Last Name", googleLastName)

        googleEmail = account?.email ?: ""
        Log.i("Google Email", googleEmail)

        val googleIdToken: String = account?.idToken ?: ""
        Log.i("Google ID Token", googleIdToken)

        googleProfilePicURL = account?.photoUrl.toString()
        Log.i("Google Profile Pic URL", googleProfilePicURL)

        firebaseAuthWithGoogle(googleIdToken)

    } catch (e: ApiException) {
        // Sign in was unsuccessful
        Log.e(
            "failed code=", e.statusCode.toString()
        )
    }
}

private fun enablePersistence() {
    // [START rtdb_enable_persistence]
    Firebase.database.setPersistenceEnabled(true)
    // [END rtdb_enable_persistence]
}

private fun firebaseAuthWithGoogle(idToken: String) {
    val credential = GoogleAuthProvider.getCredential(idToken, null)
    firebaseAuth.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")

                firebaseUserID = firebaseAuth.currentUser!!.uid
                refUsers = FirebaseDatabase.getInstance().reference.child("Users").child(firebaseUserID)
                refUsers.addListenerForSingleValueEvent(object : ValueEventListener {
                    override fun onDataChange(p0: DataSnapshot) {

                        if (p0.exists()) {
                            val user: Users? = p0.getValue(Users::class.java)
                            //Check if user exists in the database
                            if (user!!.getFirstName() != null) {
                                val intent = Intent(
                                    this@WelcomeActivity,
                                    IntroSplashScreen::class.java
                                )
                                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
                                startActivity(intent)
                                finish()
                            } else {
                                val usersHashMap = HashMap<String, Any>()
                                usersHashMap["uid"] = firebaseUserID
                                usersHashMap["firstname"] = googleFirstName
                                usersHashMap["surname"] = googleLastName
                                usersHashMap["profile"] = googleProfilePicURL
                                usersHashMap["primaryEmail"] = googleEmail
                                usersHashMap["search"] =
                                    googleFirstName.toLowerCase(Locale.ROOT)

                                refUsers.updateChildren(usersHashMap)
                                    .addOnCompleteListener {
                                        if (task.isSuccessful) {
                                            val intent = Intent(
                                                this@WelcomeActivity,
                                                NewProfileData::class.java
                                            )
                                            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
                                            startActivity(intent)
                                            finish()
                                        }

                                    }
                            }
                        }

                    }

                    override fun onCancelled(error: DatabaseError) {
                        TODO("Not yet implemented")
                    }

                })
            } else {
                // If sign in fails, display a message to the user.
                Log.w(TAG, "signInWithCredential:failure", task.exception)
                // ...

            }
            // ...
        }
}

private fun refreshIdToken() {
    // Attempt to silently refresh the GoogleSignInAccount. If the GoogleSignInAccount
    // already has a valid token this method may complete immediately.
    //
    // If the user has not previously signed in on this device or the sign-in has expired,
    // this asynchronous branch will attempt to sign in the user silently and get a valid
    // ID token. Cross-device single sign on will occur in this branch.
    mGoogleSignInClient.silentSignIn()
        .addOnCompleteListener(
            this
        ) { task -> handleSignInResult(task) }
}


override fun onStart() {
    super.onStart()
    //Checks if the Google IDToken has expired, if yes it refreshes by SilentSign in and generates new Firebase Token
    refreshIdToken()
    //Checks if user is logged in to firebase
    firebaseUser = FirebaseAuth.getInstance().currentUser
    //If logged in then sends to MainActivity
    if (firebaseUser != null) {
        startActivity(IntroSplashScreen.getLaunchIntent(this))
        finish()
    }
}

override fun onResume() {
    super.onResume()
    refreshIdToken()
}

}

1
Hi Martin, Thanks for your reply, I am signing in using Google Sign In first and then attempting to sign in using the same method given in the link you shared, but Google Login occurs, Firebase has a user in authentication but no user is in the RealTime Database in this function firebaseAuthWithGoogle(idToken: String)... adn the screen does not change... - madhall

1 Answers

0
votes

My method of checking if the user exists was incorrect with the currect process being to put the check on Datasnapshot exits or not. If exists then login else register.