🔥 FIREBASE Authentication - LOGIN con Email y CONTRASEÑA en SwiftUI
FirebaseAuth en iOS lo usamos en nuestras apps para autenticar usuarios. Utilizamos el Proveedor de Email y Password para registrar a un user y así pueda tener una sesión abierta en nuestra app.
También veremos como hacer Login y Logout con Firebase Authentication en iOS. Usaremos SwiftUI.
Hoy lo que vamos a ver es a cómo crear un método de autenticación con Firebase. Lo primero que vamos a ver es a cómo registrar users y que luego estos users puedan hacer login y logout de su sesión dentro de nuestra app.
¿Por qué queremos aplicar autenticación a nuestra app? Solo dejaremos acceder a nuestra app si el usuario se ha registrado préviamente. Una vez ha creado su sesión podrá hacer login dentro de nuestra app y podrá empezar a guardar información en una base de datos (esto lo veremos en futuros posts).
Para crear nuestra app, vamos a crear una estructura de ficheros como la que os muestro en el siguiente diagrama.
Tendremos diferentes instancias con diferentes responsabilidades:
View, vistas que crearemos con SwiftUI y que llamaran a los ViewModel para lanzar alguna acción (por ejemplo, registrar a un user con email y password).
ViewModel, será una class conformando el protocolo ObservableObject ya que tendrá propiedades que al asignar valores refrescaran la vista para que se redibuje con la nueva información. También tendrá métodos que llamaran al Repository
Repository, tendremos esta capa que de momento llamará a los métodos que creemos en nuestro Datasource
Datasource, se encargará de importar los Frameworks de terceros como por ejemplo el de Firebase, FacebookLogin, etc
Una vez hemos visto la estructura que vamos a seguir, vamos a empezar!
Creamos las vistas de inicio, login y registro en SwiftUI
Lo primero de todo que vamos hacer es crear la vistas de nuestra app y para ser más concreto, crearemos la vista de inicio de nuestra app, la primera que aparecerá al User:
Es decir, si el user no tiene ninguna sesión creada, aparecerá una primera vista para que haga login en nuestra app o se registre. La vista de inicio va a ser la siguiente:
He añadido una imagen de SwiftBeta para darle más estilo a la vista y también he añadido una systemImage de un sobre para que el button tenga más gracia.
Y la vista de login:
Y la vista de registro que será muy parecida a la de Login, solo cambiaremos algún mensaje:
Hemos creado también una vista helper, para poder dismisear vistas que hemos presentado con el modificador .sheet
Creamos el Datasource
Lo siguiente que vamos hacer es crear un fichero llamado AuthenticationFirebaseDatasource e importar la dependencia FirebaseAuth
Justo en el post anterior importamos solo las de Firebase Analytics, es por eso que al importar en esta nueva clase import FirebaseAuth nos fallará (no such module FirebaseAuth), así que vamos a arreglarlo.
Para importar estas dependencia tenemos que ir a nuestro proyecto, vamos al target de ReadLater y en la sección General hay una sección que tiene de título Frameworks, Libraries, and Embedded Content
Allí vamos a añadir solo la dependencia que necesitamos, FirebaseAuth
Una vez añadida, en nuestro datasource desaparece el error que teníamos. Vamos a seguir añadiendo código en nuestro AuthenticationFirebaseDatasource, aquí lo que queremos es crear una capa de separación con Firebase, es decir las capas superiores no sabrán nada de Firebase y por lo tanto no tendrán que importarlo por que no lo necesitaran.
Crearemos un modelo llamado User que es lo que enviaremos a las capas superiores, este modelo User no tiene nada que ver con Firebase, creamos este modelo en nuestro dominio para evitar tirar hacía las capas superiores un modelo de Firebase. Es decir, el respositorio recibirá este User, que se lo enviará al ViewModel y en el ViewModel se le asignará a una propiedad @Published que hará que pase algo en la vista. Pero vamos por partes, lo primero es crear la lógica de crear un nuevo User en nuestro AuthenticationFirebaseDatasource.
Creamos el Repository
A continuación vamos a crear nuestro repositorio.
Lo vamos a llamar AuthenticationRepository y lo que hará será llamar a los métodos de nuestro AuthenticationFirebaseDatasource:
Creamos el ViewModel
Y finalmente vamos a crear nuestro ViewModel, lo vamos a llamar AuthenticationViewModel
nuestro ViewModel llamará al método que tenemos en el repositorio que hemos creado en el paso anterior. Al registrar un nuevo usuario de forma correcta, se almacenará en la propiedad User que hará que la vista se refresque, y en caso de error al registrar un nuevo usuario (el email no está bien creado, la password no tiene un mínimo de caracteres, etc) lo mostraremos por pantalla.
Ahora lo que tenemos conectado es el ViewModel con el Repositorio y el Repositorio con el Datasource, lo que tenemos que hacer es conectar nuestro ViewModel a la vista.
Para hacerlo, nos vamos a ReadLaterApp, allí vamos a crear una propiedad @StateObject de tipo AuthenticationViewModel, y dentro de WindowGroup vamos hacer los siguiente:
Al hacerlo de esta manera, cuando un usuario se registre correctamente, la vista de registro desparecerá y aparecerá una nueva donde en el centro aparece User logged! [email protected]
Al hacer esto, tenemos que pasar la instancia de nuestro AuthenticationViewModel en la vista de AuthenticationView y en la vista de RegisterEmailView, así que AuthenticationView quedaría:
y RegisterEmailView quedaría de la siguiente manera:
En este último fíjate que hemos añadido:
Una propiedad @ObservedObject con la instancia de AuthenticationViewModel
Hemos llamado al método createNewUser cuando el button de Login es pulsado
Si al registrar un nuevo User tenemos algún error, mostramos un mensaje en la vista.
Vamos a ver qué pasos debemos seguir a continuación.
Habilitar Correo electrónico/contraseña en Firebase como sistema de autenticación
Una vez hemos añadidos nuestro Datasource -> Repository -> ViewModel y hemos conectado el ViewModel al RegisterEmailView, tenemos que ir a la consola de Firebase, y una vez allí seleccionamos del menú lateral Authentication
Al seleccionar Authentication le damos al button que aparece de Comenzar. Ahora nos aparece un vista para agreemos el método de autenticación de nuestra app. En nuestro caso, vamos a escoger de la sección de Proveedores nativos el de Correo Electrónico/contraseña.
Una vez seleccionado, lo habilitamos y pulsamos en Guardar
Ahora en Firebase podemos usar (de momento) el Proveedor de Correo electrónico/contraseña
Si vamos a la pestaña de Users, vemos que no hay ningún usuario que se haya registrado aún en nuestra app. Vamos a compilar la app y vamos a registrarnos!
Registro de nuevos users en Firebase
Ahora que tenemos todo listo:
Vista de registro conectada con el ViewModel que a su vez está conectado con el Repositorio y que el repositorio está conectado con el datasource, que hará la llamada al SDK de Firebase para añadir un nuevo user con un email y una password. (En caso de error lo controlaremos.)
Habilitado el Proveedor de Correo electrónico/contraseña
Compilamos la aplicación, nos aparece la vista de Inicio, donde podemos seleccionar el login o registro por email. Seleccionamos el registro ya que el login aún no lo tenemos implementado, lo haremos justo después de registrar nuestro User.
Clickamos en Regístrate y nos aparece la pantalla de registro
Vamos a añadir nuestro correo electrónico y una password, al acabar pulsamos en el button de Login. Si todo funciona bien deberíamos ver que nuestra vista de registro desaparece y muestra el Text que hemos puesto en ReadLaterApp.
Parece que funciona perfectamente, vamos a ver nuestra consola de Firebase y vamos a confirmar que aparece un nuevo User.
Y aquí lo tenemos! acabamos de registrar nuestro primer user en nuestra app! 🎉 Vamos a continuar.
Cargar user si hay una sesión activa
Si ahora compilamos de nuevo la app, vemos que nos lleva otra vez a la pantalla de inicio (en la que podíamos escoger el login y registro), pero en principio ya tenemos una sesión abierta, ya que de momento no hemos hecho Logout (crearemos esta lógica en breve). Vamos a arreglar que aunque lancemos otra vez la app, si hay una sesión abierta la cargue y muestre la vista con el Text User logged! [email protected].
Nos vamos al datasource, ya que como comentaba antes, es la única clase que puede utilizar Firebase, las demás son agnósticas. Y vamos a crear un método nuevo para que nos retorne el User de la sesión actual, y este User vamos hacer como antes, lo vamos a transformar, lo vamos a mapear a un objeto de nuestro dominio llamado User donde solo tiene una propiedad de tipo String, llamada email. Pues en AuthenticationFirebaseDatasource creamos un nuevo método.
Vamos a crear un método en AuthenticationRepository que llame al método que acabamos de crear en nuestro datasource.
Y finalmente lo vamos a crear en nuestro AuthenticationViewModel:
Fíjate, que aparte de crear el método getCurrentUser para recibir el User de la sesión actual, también llamamos al método al inicializar el ViewModel.
Creamos el Logout en FirebaseAuth
Una vez estamos logueados nos aparece una pantalla con un simple Text enseñando nuestro email. Vamos a crear una vista llamada HomeView y aparte de mostrar el mismo Text vamos a mostrar un Button que haga Logout. Pero antes vamos a crear el mismo proceso que antes, vamos a crear el método de logout en el datasource, luego en el repo, luego en el viewmodel y a continuación crearemos la nueva vista HomeView que al pulsar el button de Logout llamará al método del ViewModel.
En AuthenticationFirebaseDatasource añadimos:
En el repositorio de AuthenticationRepository añadimos:
Y en el ViewModel creamos un nuevo método:
Fíjate que aquí hemos usado do y catch para ver si ha habido un error al cerrar la sesión al User. En caso de que todo vaya bien, asignamos a User nil para que vuelva aparecer la pantalla de Inicio de la app. Y en caso de error, mostramos un print por consola.
Cuando hemos acabado de añadir este nuevo método, creamos la vista HomeView:
Y por lo tanto modificamos nuestro fichero (y struct) ReadLaterApp:
Creamos la lógica del Login con FirebaseAuth en SwiftUI
Lo último que nos falta por crear es el Login de nuestra app. Es decir, hasta ahora hemos creado el registro y hemos hecho el Logout. Vamos a crear el Login. Esta va a ser la parte más fácil, ya que es muy parecido a los pasos del Registro. Lo primero de todo que vamos hacer es crear un método en AuthenticationFirebaseDatasource:
En nuestro repositorio vamos a crear un método que llame al nuevo método que acabamos de crear en nuestro datasource:
Y finalmente lo creamos en nuestro AuthenticationViewModel:
Finalmente, AuthenticationViewModel se lo inyectamos a nuestra vista LoginEmailView:
Fíjate que:
Hemos creado la propiedad AuthenticationViewModel
Hemos conectado el button Login con el método login de nuestro AuthenticationViewModel
Hemos añadido un Text en caso de recibir un error de Firebase al hacer login, así damos feedback al user de qué está pasando.
Finalmente, tenemos que pasarle la instancia de AuthenticationViewModel a nuestra vista LoginEmailView y quedaría de la siguiente manera:
Si ahora compilamos nuestra app, vamos a probar que podemos hacer un Login. Al ejecutar la app en el simulador nos aparece la pantalla de inicio, aquí vamos a escoger Entrar con Email para hacer el Login. Si probamos con los credenciales de nuestro User registrado hace el Login perfectamente 🎉
Si quieres que en la app no se vea la contraseña, en lugar de usar un TextField, puedes usar un SecureField
Al acabar de crear el login con email y password, voy a estructurar un poco nuestros ficheros en Xcode.
Voy a dejar preparada esta estructura para futuros posts.
Conclusión
Hoy hemos visto a como registrar, loguear o desloguear a un user usando el proveedor Email y Password de Firebase dentro de nuestra app. Con esta autenticación creamos una capa extra de seguridad en nuestra app para solo permitir usuarios con permisos realicen ciertas acciones.
Curso Firebase desde cero para crear una aplicación iOS. Aprende a crear autenticación, usar bases de datos Cloud Firestore, enviar push notifications, crear test a/b, trackear eventos, y muchos más!
Este video de 3 horas te guiará paso a paso para crear tu app iOS.
Aprende a enviar Push Notifications con Firebase. Solo tenemos que crear un APNs en el portal de Apple y subirlo a Firebase. Dentro de Cloud Messaging podemos crear nuestra Push Notification con un título y mensaje y enviarla a todos nuestros users.