En esta entrada voy a explicar cómo incluir un login en tu aplicación, con la posibilidad de iniciar sesión mediante usuario y contraseña o con Google.
Todo esto lo vamos a realizar con Firebase, la nueva y mejorada plataforma de desarrollo móvil creada por Google, cuya principal función es desarrollar y facilitar la creación de apps de elevada calidad de una forma rápida, con el fin de que se pueda aumentar la base de usuarios y ganar más dinero. La plataforma está subida en la nube y está disponible para diferentes plataformas como iOS, Android y web.
Las posibilidades que nos ofrece Firebase para el desarrollo son:
Por si necesitáis más información, aquí os dejo un enlace con toda la documentación.
Configuración
Voy a explicar lo mas fácil posible lo que necesitamos para poder empezar a escribir código. Lo que vamos a hacer es conectar nuestro IDE -Android Studio- con Google Firebase a través de su asistente, ya que este nos ayudará a crear un proyecto en Firebase y conectarlo a la App . Para conectarlo con Android Studio hay que seguir los siguientes pasos:
- Ir a «Tools» -> «Firebase»
- Se abrirá un asistente. Entre todas las posibilidades hay que seleccionar «Authentication» y «Email and password authetication»
- Pulsamos en «Conect to Firebase»
- Elegimos «Create new Firebase project» y ponemos un nombre al proyecto.
- Por último pulsamos la opción «Add Firebase Authentication to your app» . Esto nos descarga un fichero JSON con toda la información de nuestro proyecto.
Una vez hecho esto, es hora de dirigirnos a la consola de Firebase. Ahora configuraremos los dos inicios de sesión para nuestra app:
-
- Abrir la consola, seleccionar el proyecto creado con Android Studio y pulsar en «Authentication».
-
- Ir a «Métodos de acceso» .
- Habilitar «Correo electrónico/contraseña» y «Google»
Código
Ahora ya podemos empezar a escribir el código. La estructura de mi proyecto es la siguiente:
Si os habéis fijado, estoy utilizando Kotlin en vez de Java, ya que me parecía mas interesante utilizar este nuevo lenguaje cada vez mas utilizado a día de hoy.
Diseño
activity_login.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="56dp" android:paddingLeft="24dp" android:paddingRight="24dp"> <ImageView android:layout_width="wrap_content" android:layout_height="72dp" android:layout_marginBottom="24dp" android:layout_gravity="center_horizontal" /> <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginBottom="8dp"> <EditText android:id="@+id/input_email" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textEmailAddress" android:hint="Email" /> </android.support.design.widget.TextInputLayout> <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginBottom="8dp"> <EditText android:id="@+id/input_password" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPassword" android:hint="Password"/> </android.support.design.widget.TextInputLayout> <TextView android:id="@+id/link_olvidar" android:layout_width="fill_parent" android:layout_height="wrap_content" android:autoLink="web" android:text="@string/label_olvidada_contraseña" android:gravity="center" android:textAppearance="?android:attr/textAppearanceSmall"/> <android.support.v7.widget.AppCompatButton android:id="@+id/btn_login" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:layout_marginBottom="24dp" android:padding="12dp" android:text="Login"/> <TextView android:id="@+id/link_signup" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="24dp" android:autoLink="web" android:text="@string/label_login" android:gravity="center" android:textAppearance="?android:attr/textAppearanceSmall"/> <com.google.android.gms.common.SignInButton android:id="@+id/boton_login_google" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" app:buttonSize="wide" app:colorScheme="auto" android:textAlignment="center" android:layout_marginTop="50dp" /> </LinearLayout> </ScrollView> |
Desarrollo
Modelo.kt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
package com.albrivas.login_firebase.utils import android.app.ProgressDialog import android.content.Context import android.net.ConnectivityManager import android.net.NetworkInfo import android.support.v7.app.AppCompatActivity import android.view.WindowManager import com.google.android.gms.auth.api.signin.GoogleSignInClient import com.google.firebase.auth.FirebaseAuth import dmax.dialog.SpotsDialog public class Modelo { private lateinit var alertDialog: android.app.AlertDialog private lateinit var progressDialog: ProgressDialog //COMPROBAR CONEXION INTERNET. fun compruebaConexion(context: Context): Boolean { var connected = false val connec = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager // Recupera todas las redes (tanto móviles como wifi) val redes = connec.allNetworkInfo for (i in redes.indices) { // Si alguna red tiene conexión, se devuelve true if (redes[i].state == NetworkInfo.State.CONNECTED) { connected = true } } return connected } // Hacer actividades transprentes. fun activityTransparent(activity: AppCompatActivity) { activity.window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) } //Dialogo perso. fun showDialog(contexto: Context, mensage: String) { alertDialog = SpotsDialog(contexto, mensage) alertDialog.show() } // Cerrar dialogo. fun hideDialog() { alertDialog.dismiss() } // DIALOGO NORMAL. fun showProgressDialog(title: String, message: String, contexto: Context) { if (progressDialog != null && progressDialog.isShowing) progressDialog.setMessage(message) else progressDialog = ProgressDialog.show(contexto, title, message, true, false) } // CERRAR DIALOGO. fun hideProgressDialog() { if (progressDialog != null) progressDialog.hide() } // Cerrar sesiones. fun signOut(auth: FirebaseAuth, client: GoogleSignInClient) { auth.signOut() client.signOut() } } |
Login.kt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
package com.albrivas.login_firebase import android.content.Intent import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.text.TextUtils import android.view.View import android.widget.Button import android.widget.EditText import android.widget.Toast import com.google.android.gms.auth.api.signin.GoogleSignIn import com.google.android.gms.auth.api.signin.GoogleSignInAccount import com.google.android.gms.auth.api.signin.GoogleSignInClient import com.google.android.gms.auth.api.signin.GoogleSignInOptions import com.google.android.gms.common.SignInButton import com.google.android.gms.common.api.ApiException import com.google.firebase.auth.FirebaseAuth import com.google.firebase.auth.GoogleAuthProvider import com.albrivas.login_firebase.utils.Modelo class Login : AppCompatActivity(), View.OnClickListener { private lateinit var mAuth: FirebaseAuth private lateinit var mGoogleSignInClient: GoogleSignInClient private lateinit var googleSignInOptions: GoogleSignInOptions private lateinit var emailUsuario: EditText private lateinit var passUsuario: EditText private lateinit var btnLogin: Button private lateinit var btnLoginGoogle: SignInButton private val RC_SIGN_IN: Int = 123 private lateinit var modelo: Modelo override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_login) instanciasFirebase() instanciasGoogle() instancias() acciones() //modelo.activityTransparent(this@Login) } override fun onStart() { super.onStart() if (mAuth.currentUser != null) { startActivity(Intent(this@Login, Principal::class.java)) finish() } } private fun instanciasGoogle() { googleSignInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken(getString(R.string.default_web_client_id)) .requestEmail() .build() mGoogleSignInClient = GoogleSignIn.getClient(this, googleSignInOptions) } private fun instanciasFirebase() { mAuth = FirebaseAuth.getInstance() //Autenticacion de Firebase } private fun instancias() { emailUsuario = findViewById(R.id.input_email) passUsuario = findViewById(R.id.input_password) btnLogin = findViewById(R.id.btn_login) btnLoginGoogle = findViewById(R.id.boton_login_google) modelo = Modelo() } private fun acciones() { btnLogin.setOnClickListener(this) btnLoginGoogle.setOnClickListener(this) } private fun signInFirebase(email: String, password: String) { // Validamos los datos introducidos if (TextUtils.isEmpty(email)) { Toast.makeText(applicationContext, getString(R.string.email_introducir), Toast.LENGTH_SHORT).show() return } if (TextUtils.isEmpty(password)) { Toast.makeText(applicationContext, getString(R.string.pass_introducir), Toast.LENGTH_SHORT).show() return } if (password.length < 6) { passUsuario.error = getString(R.string.pass_longitud) return } modelo.showDialog(this@Login, getString(R.string.dialog_sesion)) mAuth.signInWithEmailAndPassword(email, password). addOnCompleteListener(this) {task -> if(task.isSuccessful) { modelo.hideDialog() startActivity(Intent(this@Login, Principal::class.java)) finish() } else { modelo.hideDialog() Toast.makeText(applicationContext, getString(R.string.error_autenticacion_usuario), Toast.LENGTH_SHORT).show() } } } private fun signInGoogle() { val intent = mGoogleSignInClient.signInIntent startActivityForResult(intent, 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) try { //Inicio de sesion correcto, autenticamos con firebase val account= task.getResult(ApiException::class.java) firebaseAuthGooogle(account) } catch (e: ApiException) { Toast.makeText(this@Login, getString(R.string.error_conexion), Toast.LENGTH_LONG).show() } } } private fun firebaseAuthGooogle(account: GoogleSignInAccount) { modelo.showDialog(this@Login, getString(R.string.dialog_sesion)) val credential = GoogleAuthProvider.getCredential(account.idToken, null) mAuth.signInWithCredential(credential).addOnCompleteListener(this) { task -> if(task.isSuccessful) { modelo.hideDialog() startActivity(Intent(this@Login, Principal::class.java)) finish() } else { modelo.hideDialog() Toast.makeText(this@Login, getString(R.string.error_login), Toast.LENGTH_LONG).show() } } } override fun onClick(p0: View?) { when (p0?.id) { R.id.btn_login -> { if(modelo.compruebaConexion(applicationContext)) { signInFirebase(emailUsuario.text.toString(), passUsuario.text.toString()) } else { Toast.makeText(this@Login, getString(R.string.error_conexion), Toast.LENGTH_LONG).show() } } R.id.boton_login_google -> { if(modelo.compruebaConexion(applicationContext)) { signInGoogle() } else { Toast.makeText(this@Login, getString(R.string.error_conexion), Toast.LENGTH_LONG).show() } } } } } |
Por si alguien necesita ver el proyecto completo, os dejo el enlace a mi repositorio
*Nota: para poder usar Kotlin en Android, debes habilitar la opción de «Include Kotlin support» cuando crees el proyecto en Android Studio. Aparece en la primera pantalla
0 comentarios