
🔥 FIREBASE LOGIN con Facebook en SwiftUI y en Español #3
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.
Tabla de contenido

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.

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

- 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.

Una vez logeados debemos empezar nuestro registro usando el siguiente enlace:
Deberemos rellenar una serie de pasos antes de poder crear nuestra app en Facebook:

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.

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

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

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

Seleccionamos el tipo de nuestra app
A continuación nos aparecerá una serie de opciones, en mi caso escogeré la de Consumidor

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

Al hacerlo aparecerá la siguiente pantalla, aquí debemos navegar a 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.

- 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

Ahora podemos clickar en Guardar y volvemos a nuestra app de 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

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
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:

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

Una vez añadida esta dependencia podemos continuar:

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

La siguiente sección la dejamos marcada como no:

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 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>
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:

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
}
}
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"))
}
}
}
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 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)
}
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
}
}
}
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)
}
}
}
}
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.

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

Le damos a Continue

Le damos a Continuar

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

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.