Sto realizzando un'app, per adesso mi sto concentrando sull'autenticazione che dovrà avvenire tramite email e password oppure tramite account social Google, FB e Twitter.
La struttura è questa:
- main activity per adesso vuota, con un pulsante "Login"
- il pulsante "Login" porta a LoginActivity dove ci sono i campi per email e password ed i pulsanti per l'accesso coi social network
- ogni metodo di accesso ha la sua activity dedicata
- dopo il login si torna nemma MainActivity dove compare un pulsante per il logout e l'id dell'utente registrato su Firebase
Il login funziona sia con email e password, sia con Google (gli altri ancora non li sviluppo), il problema sorge al momento del logout, quando arrivo al codice per eseguirlo ricevo l'errore
java.lang.IllegalStateException: GoogleApiClient is not connected yet.
anche se in realtà l'utente è connesso, terminando e riaprendo l'app, nella MainActivity compare l'id dell'utente.
Ricapitolando:
MainActivity -> premo "Login" -> vado su LoginActivity -> click sul pulsante di Google -> parte GoogleAuthActivity e mi loggo -> torno a MainActivity regolarmente e visualizzo l'id -> click su "Google Logout" -> parte GoogleAuthActivity ma all'esecuzione del logout parte l'eccezione
Un po' (purtroppo tanto anche se tagliato del non necessario) di codice
MainActivity
codice:
class MainActivity : Activity(), View.OnClickListener {
private val GOOGLE_RC = 2
private val RESULT_OK = 1
private var mAuth: FirebaseAuth? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mAuth = FirebaseAuth.getInstance()
val user: FirebaseUser? = mAuth!!.currentUser
if (user != null) {
detailTV.text = "Firebase User ID: " + user.uid
btn_verify_email.isEnabled = !user.isEmailVerified
} else {
detailTV.text = "Firebase User ID: 12345"
}
btn_sign_out_google.setOnClickListener(this)
}
override fun onClick(view: View?) {
val i = view!!.id
when (i) {
R.id.btn_login -> {
val intent = Intent(this, LoginActivity::class.java)
startActivity(intent)
}
R.id.btn_sign_out_google -> {
val bundle = Bundle()
bundle.putString("action", "signout")
val intent = Intent(this, GoogleAuthActivity::class.java)
intent.putExtras(bundle)
startActivityForResult(intent, GOOGLE_RC)
}
}
}
}
GoogleAuthActivity
codice:
class GoogleAuthActivity : FragmentActivity(), GoogleApiClient.OnConnectionFailedListener {
private val GOOGLE_RC = 2
private val RESULT_OK = 1
private val RESULT_KO = 0
private var mAuth: FirebaseAuth? = null
private var mGoogleApiClient: GoogleApiClient? = 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))
.requestEmail()
.build()
mGoogleApiClient = GoogleApiClient.Builder(this)
.enableAutoManage(this, this)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build()
mAuth = FirebaseAuth.getInstance()
val bundle = this.intent.extras
val action = bundle.getString("action")
when(action) {
"signin" -> signIn()
"signout" -> signOut()
}
}
private fun signIn() {
val intent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient)
startActivityForResult(intent, GOOGLE_RC)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent();
if (requestCode == GOOGLE_RC) {
val result = Auth.GoogleSignInApi.getSignInResultFromIntent(data)
if (result.isSuccess) {
// successful -> authenticate with Firebase
val account = result.signInAccount
firebaseAuthWithGoogle(account!!)
} else {
val response = Intent(this, LoginActivity::class.java)
response.putExtra("result", RESULT_KO)
setResult(GOOGLE_RC,response)
finish()
}
}
}
private fun firebaseAuthWithGoogle(acct: GoogleSignInAccount) {
Log.e(TAG, "firebaseAuthWithGoogle():" + acct.id!!)
val credential = GoogleAuthProvider.getCredential(acct.idToken, null)
mAuth!!.signInWithCredential(credential)
.addOnCompleteListener(this) { task ->
val response = Intent(this, LoginActivity::class.java)
response.putExtra("action", "social_signin")
if (task.isSuccessful) {
// Sign in success
Log.e(TAG, "signInWithCredential: Success!")
response.putExtra("result", RESULT_OK)
setResult(GOOGLE_RC,response)
finish()
} else {
// Sign in fails
Log.w(TAG, "signInWithCredential: Failed!", task.exception)
response.putExtra("result", RESULT_KO)
setResult(GOOGLE_RC,response)
finish()
}
}
}
private fun signOut() {
// logout from Google
Auth.GoogleSignInApi.signOut(mGoogleApiClient)
// logout from Firebase
mAuth!!.signOut()
val response = Intent(this, LoginActivity::class.java)
response.putExtra("action", "signout")
response.putExtra("result", RESULT_OK)
setResult(GOOGLE_RC,response)
finish()
}
}
E' come se mGoogleApiClient da qualche parte venisse invalidato perché se controllo mGoogleApiClient.isConnected risulta false.
Idee da cosa possa dipendere?
Su Stackoverflow leggevo che capita se si creano 2 o più istanze dell'oggetto GoogleApiClient, ma non mi pare di crearne più di una, sbaglio?