Firebase Tutorial iOS - Autenticación con Email y Contraseña
Firebase Tutorial iOS - Autenticación con Email y Contraseña

🔥 FIREBASE LOGIN con Facebook en SwiftUI y en Español #4

Login Facebook en iOS con Firebase. Usa Facebook como método de autenticación con Firebase en Swift, para ello debemos crear una app en Facebook Developers y configurar nuestro proyecto de Xcode. Así un user podrá registrarte y crear una sesión dentro de nuestra app.

SwiftBeta

Tabla de contenido

Aprende a crear un Login con Facebook en Firebase

Hoy lo que vamos a ver es otro método de autenticación dentro de nuestra app. Vamos a crear el login en SwiftUI con Facebook en Firebase.

Lo primero de todo que necesitamos es irnos a nuestra consola de Firebase y añadir el nuevo proveedor de autenticación, que será Facebook (Meta).

Añadir Facebook como nuevo proveedor de autenticación en Facebook

Para hacerlo, nos vamos a la sección de autenticación y nos vamos al tab de Sign-in method, aquí dentro clickamos en Agregar proveedor nuevo.

Agregamos Facebook como nuevo Proveedor en Firebase Autentication.
Agregamos Facebook como nuevo Proveedor en Firebase Autentication. 

Al agregar el proveedor de Facebook, vemos que nos pide información:

Al configurar Facebook como nuevo provvedor aparece información que no tenemos
Al configurar Facebook como nuevo provvedor aparece información que no tenemos
  • Id de la app
  • Secreto de app

Esta información aún no la tenemos. Necesitamos un paso prévio y es crear nuestra app en Facebook Developers. Pues, vamos a ello:

Creamos la cuenta de Facebook Developers

Lo primero de todo que necesitamos es tener una cuenta de Facebook developers.

Facebook for Developers
Code to connect people with Facebook for Developers. Explore AI, business tools, gaming, open source, publishing, social hardware, social integration, and virtual reality. Learn about Facebook’s global programs to educate and connect developers.

Una vez logeados debemos empezar nuestro registro usando el siguiente enlace:

Aanmelden bij Facebook
Meld je aan bij Facebook om te delen en contact te maken met je vrienden, familie en mensen die je kent.

Deberemos rellenar una serie de pasos antes de poder crear nuestra app en Facebook:

Creamos una cuenta de Facebook para desarrolladores
Creamos una cuenta de Facebook para desarrolladores

Verificamos cuenta

Para verificar la cuenta debemos añadir nuestro número de teléfono. Allí recibiremos un código de verificación que deberemos añadir en este paso.

Verificamos nuestra cuenta de Facebook Developers
Verificamos nuestra cuenta de Facebook Developers

El siguiente paso es añadir un correo electrónico de contacto:

Añadimos nuestro email
Añadimos nuestro email 

y finalmente seleccionamos una de las siguientes opciones, en mi caso he escogido desarrollador y pulsamos en completar registro:

Como último paso seleccionams que somos Desarrolladores
Como último paso seleccionams que somos Desarrolladores

Creamos la aplicación en Facebook

Después de seguir los pasos de nuestro registro, nos aparecerá la siguiente sección. Aquí podemos crear nuestra aplicación, así que pulsamos Crear aplicación

Creamos la aplicación en Facebook Developers
Creamos la aplicación en Facebook Developers

Seleccionamos el tipo de nuestra app

A continuación nos aparecerá una serie de opciones, en mi caso escogeré la de Consumidor

Seleccionamos el tipo de aplicación. En nuestro caso sera Consumidor
Seleccionamos el tipo de aplicación. En nuestro caso sera Consumidor

y cómo último paso añadimos el nombre de nuestra app y pulsamos en Crear aplicación

Añadimos un nombre a nuestra app
Añadimos un nombre a nuestra app 

Al hacerlo aparecerá la siguiente pantalla, aquí debemos navegar a Configuración

Navegamos al menú lateral izquierdo. A la opción de Configuración
Navegamos al menú lateral izquierdo. A la opción de Configuración

En esta sección, en la Información básica nos aparecen dos datos que necesitamos para integrar este nuevo proveedor en Firebase.

En Información Básica aparece la información necesaria que aparecía en el formulario de Firebase
En Información Básica aparece la información necesaria que aparecía en el formulario de Firebase
  • Identificador de la aplicación: 1120058398758935
  • Clave Secreta de la aplicación: e55ee9db43aa9882d947a3e24d2c251c

Ahora sí, con esta información ya podemos añadir Facebook como proveedor de autenticación en Firebase.

Configuramos Firebase como proveedor de autenticación en Facebook

Añadimos el AppId y la Clave Secreta de la app

En Firebase añadimos la información de la App que acabamos de crear en Facebook Developers
En Firebase añadimos la información de la App que acabamos de crear en Facebook Developers

Ahora podemos clickar en Guardar y volvemos a nuestra app de Facebook

Vamos a configurar el Inicio de sesión con Facebook
Vamos a configurar el Inicio de sesión con Facebook

Aquí vamos a añadir un producto a nuestra aplicación, el producto se llama Inicio de sesión con Facebook y clickamos en Configurar, aquí vamos a tener que rellenar varios pasos.

Configurar Inicio de Sesión con Facebook

Seleccionamos iOS como plataforma

Seleccionamos la opción iOS
Seleccionamos la opción iOS

Añadimos Swift Package Manager, este paso no lo explica muy bien, pero debemos añadir la dependencia de Facebook en nuestro proyecto de Xcode. Para ello vamos a usar Swift Package Manager. Nos vamos a File -> Add Packages y pegamos la siguiente URL

GitHub - facebook/facebook-ios-sdk: Used to integrate the Facebook Platform with your iOS & tvOS apps.
Used to integrate the Facebook Platform with your iOS & tvOS apps. - GitHub - facebook/facebook-ios-sdk: Used to integrate the Facebook Platform with your iOS & tvOS apps.

Lo único que quiero recalcar es que solo necesitamos FacebookLogin así que marca solo esa opción al escoger que paquetes que quieres integrar en Xcode:

Añadimos los paquetes necesarios para poder usar FacebookLogin en nuestra app.
Añadimos los paquetes necesarios para poder usar FacebookLogin en nuestra app.

Si tienes dudas de cómo añadir dependencias con Swift Package Manager, mira el siguiente post:

Swift Package Manager - Añadir código SWIFT de otros developers en nuestra APP
Cómo usar Swift Package Manager para añadir dependencias, frameworks o paquetes de otros developers. Swift Package Manager está integrado en Xcode y de una manera muy rápida, con una simple URL de Github podríamos integrar código Swift a nuestra app y estar listos para usarlo.

Una vez añadida esta dependencia podemos continuar:

Le damos  Siguiente y continuamos con los siguientes pasos
Le damos Siguiente y continuamos con los siguientes pasos

El siguiente paso es añadir el Bundler de nuestra app:

En este paso, añadimos el bundle id de nuestra app: com.swiftbeta.ReadLater
En este paso, añadimos el bundle id de nuestra app: com.swiftbeta.ReadLater

La siguiente sección la dejamos marcada como no:

En el siguiente paso no marcamos la opción de Activar el inicio de sesión único
En el siguiente paso no marcamos la opción de Activar el inicio de sesión único

Ahora tenemos que modificar el Info.plist para ello, copiamos el que nos sale aquí y nos vamos a Xcode. Para poder añadir estos nuevos campos pulsamos encima del Info.plist con el botón derecho y lo abrimos como Source Code

En este paso tenemos que modificar nuestro Info.plist en Xcode
En este paso tenemos que modificar nuestro Info.plist en Xcode

En mi caso, mi Info.plist quedaría de la siguiente manera:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <array>
      <dict>
      <key>CFBundleURLSchemes</key>
      <array>
        <string>fb1120058398758935</string>
      </array>
      </dict>
    </array>
    <key>FacebookAppID</key>
    <string>1120058398758935</string>
    <key>FacebookClientToken</key>
    <string>9238b15bbdcfe29db5519d9ecd9ff71f</string>
    <key>FacebookDisplayName</key>
    <string>ReadLater</string>
    <key>LSApplicationQueriesSchemes</key>
    <array>
      <string>fbapi</string>
      <string>fbapi20130214</string>
      <string>fbapi20130410</string>
      <string>fbapi20130702</string>
      <string>fbapi20131010</string>
      <string>fbapi20131219</string>
      <string>fbapi20140410</string>
      <string>fbapi20140116</string>
      <string>fbapi20150313</string>
      <string>fbapi20150629</string>
      <string>fbapi20160328</string>
      <string>fbauth</string>
      <string>fb-messenger-share-api</string>
      <string>fbauth2</string>
      <string>fbshareextension</string>
    </array>
</dict>
</plist>
Fichero Info.plist en Xcode con la configuración de Facebook SDK

Y vamos a Xcode para fijarnos que en URL Types tenemos un URL Schemes con el formato de id y el número de identificador de nuestra app:

En nuestro proyecto, en la sección Info debemos ver en URL Types la siguiente información
En nuestro proyecto, en la sección Info debemos ver en URL Types la siguiente información

Ahora ya podemos ir a nuestro código para añadir Facebook como nuevo método de Login. Para ello tocaremos varias capas para hacerlo lo más limpio posible.

Añadimos Login de Facebook en Xcode

En nuestro AppDelegate importamos el framerwork de FacebookLogin y añadimos el siguiente código:

class AppDelegate: NSObject, UIApplicationDelegate {
    
    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
        FirebaseApp.configure()
        return true
    }
}
Añadimos la inicialización de Facebook en nuestro AppDelegate

Lo siguiente que vamos hacer es crear una carpeta llamada FacebookAuthentication y ahí dentro crearemos una clase llamada FacebokAuthentication (esta clase la usaremos dentro de AuthentiationFirebaseDatasource)

import Foundation
import FacebookLogin

final class FacebookAuthentication {
    let loginManager = LoginManager()
    
    func loginFacebook(completionBlock: @escaping (Result<String, Error>) -> Void) {
        loginManager.logIn(permissions: ["email"], from: nil) { loginManagerLoginResult, error in
            if let error = error {
                print("Error login with Facebook \(error.localizedDescription)")
                completionBlock(.failure(error))
                return
            }
            let token = loginManagerLoginResult?.token?.tokenString
            completionBlock(.success(token ?? "Empty Token"))
        }
        
    }
    
}
Creamos una clase nueva en Swift que se encarga del login con Facebook

Esta nueva clase la instanciaremos desde AuthenticationFirebaseDatasource, para ello crearemos una propiedad nueva y un método nuevo que llamará al login con Facebook y si todo va bien llamara a Firebase para loguear/crear el user.

    let facebookAuthentication = FacebookAuthentication()


	func loginWithFacebook(completionBlock: @escaping (Result<User, Error>) -> Void) {
        facebookAuthentication.loginFacebook { result in
            switch result {
            case .success(let accessToken):
                let credential = FacebookAuthProvider.credential(withAccessToken: accessToken)
                Auth.auth().signIn(with: credential) { authDataResult, error in
                    if let error = error {
                        print("Error creating a new user \(error.localizedDescription)")
                        completionBlock(.failure(error))
                        return
                    }
                    let email = authDataResult?.user.email ?? "No email"
                    print("New user created with info \(email)")
                    completionBlock(.success(.init(email: email)))
                }
            case .failure(let error):
                print("Error signIn with Facebook \(error.localizedDescription)")
                completionBlock(.failure(error))
            }
        }
    }
    
Creamos un método en el datasource que llama a la nueva clase FacebookAuthentication

Creamos también el método en el AuthenticationRepository que llamará a nuestro nuevo método del AuthenticationFirebaseDatasource

    func loginFacebook(completionBlock: @escaping (Result<User, Error>) -> Void) {
        authenticationFirebaseDatasource.loginWithFacebook(completionBlock: completionBlock)
    }
Creamos el método en el repositorio que llama al método del datasource

Y finalmente conectaremos el método del repositorio con nuestro AuthenticationViewModel:

    func loginFacebook() {
        authenticationRepository.loginFacebook() { [weak self] result in
            guard let self = self else { return }
            switch result {
            case .success(let newUser):
                self.user = newUser
            case .failure(let error):
                self.messageError = error.localizedDescription
            }
        }
    }
Creamos el método en el ViewModel para poderlo llamar desde la vista en SwiftUI

Ahora solo nos falta conectar la AuthenticationView con nuestro AuthenticationViewModel, para ello creamos un Button nuevo en SwiftUI para empezar la autenticacón con Facebook. Creamos un Button con title Entra con Facebook.

En mi caso tengo una foto del icono de Facebook llamada facebook si no tienes ninguna a mano puedes utilizar cualquier otra imagen. El propósito del video es parender hacer el Login con Facebook

Lo que vamos hacer también es que en caso de detectar un error, lo vamos a mostrar en la pantalla de AuthenticationView para ello vamos a mostrar un Text siempre que tengamos un error en nuestra autenticación:

struct AuthenticationView: View {
    @ObservedObject var authenticationViewModel: AuthenticationViewModel
    @State private var authenticationSheetView: AuthenticationSheetView?
    
    var body: some View {
        VStack {
            Image("swiftbeta")
                .resizable()
                .frame(width: 200, height: 200)
            VStack {
                Button(action: {
                    authenticationSheetView = .login
                }, label: {
                    Label("Entra con Email", systemImage: "envelope.fill")
                })
                .tint(.black)
                Button(action: {
                    authenticationViewModel.loginFacebook()
                }, label: {
                    Label("Entra con Facebook", image: "facebook")
                })
                .tint(.blue)
            }
            .controlSize(.large)
            .buttonStyle(.bordered)
            .buttonBorderShape(.capsule)
            .padding(.top, 60)
            if let messageError = authenticationViewModel.messageError {
                Text(messageError)
                    .bold()
                    .font(.body)
                    .foregroundColor(.red)
                    .padding(.top, 20)
                    .padding(.horizontal, 40)
            }
            Spacer()
            HStack {
                Button {
                    authenticationSheetView = .register
                } label: {
                    Text("¿No tienes cuenta?")
                    Text("Regístrate")
                        .underline()
                }
                .tint(.black)
            }
        }
        .sheet(item: $authenticationSheetView) { sheet in
            switch sheet {
            case .register:
                RegisterEmailView(authenticationViewModel: authenticationViewModel)
            case .login:
                LoginEmailView(authenticationViewModel: authenticationViewModel)
            }
        }
    }
}
Conectamos la vista en SwiftUI con el ViewModel y creamos el Button de Facebook en SwiftUI

Vamos a probar la app y ver si funciona

Antes de todo vamos a borrar todos los users de nuestra base de datos. Así nos aseguramos que no hay ningún user con el mismo email. Este caso lo solventaremos en la siguiente sección.
AuthenticationView mostrando los dos métodos de autenticación disponibles
AuthenticationView mostrando los dos métodos de autenticación disponibles

Le damos al Button de Entra con Facebook y veremos que empieza un flujo de autenticación con Facebook:

Al pulsar en Facebook nos aparece un Alert que nos indica que nuestra app quiere hacer login con Facebook
Al pulsar en Facebook nos aparece un Alert que nos indica que nuestra app quiere hacer login con Facebook

Le damos a Continue

Rellenamos la información de Login y le damos a continuar
Rellenamos la información de Login y le damos a continuar

Le damos a Continuar

Si todo va bien, deberíamos ver la vista HomeView
Si todo va bien, deberíamos ver la vista HomeView

y nos aparece la pantalla de HomeView indicando que hemos autenticado al user correctamente. Si ahora vamos al panel de autenticación de Firebase, vemos que aparece el user

Funciona el nuevo método de autenticación con Facebook y Firebase
Funciona el nuevo método de autenticación con Facebook y Firebase

Para hacer esta prueba he limpiado mi base de datos, he eliminado el único user que tenía. Si ahora intento hacer login con email y password usando el mismo correo que tengo en Facebook, aparece un error. Tenemos que vincular de alguna manera estas dos cuentas (ya que son del mismo usuario y no nos interesa crear dos cuentas diferentes para cuando entre con Facebook y cuando entre con Email y Password).

Si intento registrarme con el mismo email nos aparece el siguiente error:

Conclusión

Hoy hemos aprendido a cómo añadir un nuevo proveedor de autenticación en Firebase. En este caso hemos usado Facebook. En el próximo posts veremos a cómo vincular distintas cuentas, así dejaremos que un user pueda entra a nuestra app y compartir la misma sesión si entra con su email y password, Facebook, Google, etc.

Si quieres seguir aprendiendo sobre SwiftUI, Swift, Xcode, o cualquier tema relacionado con el ecosistema Apple