Autenticación con Facebook en Ionic con Firebase

En posts anteriores vimos cómo utilizar Firebase con Ionic para autenticar usuarios registrar y autenticar usuarios utilizando correo y contraseña; en esta ocasión vamos a ver cómo utilizar el proveedor de Facebook de Firebase para autenticar nuestros usuarios con su cuenta de Facebook.

firebase-ionic-facebook

Prerrequisitos

Por comodidad vamos a adicionar esta funcionalidad a la aplicación que ya empezamos a implementar en los posts anteriores por lo que les recomiendo que lean esos posts primeramente y luego regresen a este.

Aplicación de Facebook

Por supuesto, para poder permitir autenticacion con Facebook necesitamos tener creada una aplicacion de facebook, lo cual podemos hacer en el sitio de desarrolladores de Facebook. Hay muchos articulos sobre como hacerlo por lo que no vamos a entrar en detalles sobre esto, sólo mencionar que vamos a necesitar el App Id de la aplicacion que creemos.

Plugin de Cordova y wrapper de Facebook de Ionic Native

Necesitaremos este plugin y su wrapper de Ionic Native porque vamos a utilizar (de estar disponible) la integración nativa a través de la app de Facebook, de lo contrario vamos a utilizar el navegador para integrarnos.

Para instalarlos, nos colocamos en la carpeta de nuestro proyecto y ejecutamos el comando que veremos a continuación, pero antes, debemos obtener y reemplazar el valor de APP_ID con el “App Id” de nuestra app de Facebook y de igual manera con APP_NAME:

ionic cordova plugin add cordova-plugin-facebook4 --variable APP_ID="1911595049109511" --variable APP_NAME="IonFire"

Con el comando anterior instalamos el plugin de Cordova, antes de seguir quiero mostrar lo que sucedió en mi caso:

Instalando plugin de Cordova de Facebook
Instalando plugin de Cordova de Facebook

Noten como durante la instalación tuve que actualizar un plugin del CLI de Ionic e instalar uno nuevo, esto es debido a que el nuevo CLI de Ionic está organizado ahora por plugins, los cuales vamos a ir instalando a medida que los vayamos necesitando, por ejemplo los comandos relacionados con el CLI de Cordova (como ionic cordova plugin add) se encuentran en @ionic/cli-plugin-cordova por lo cual me ha pedido que lo instale.

Aún falta instalar el Wrapper de Ionic Native, el cual instalaremos ejecutando:

npm install --save @ionic-native/facebook

Finalmente necesitamos registrar el plugin en el módulo principal de nuestra aplicación que se encuentra en src/app/app.module.ts:


import { BrowserModule } from '@angular/platform-browser';
import { ErrorHandler, NgModule } from '@angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { SplashScreen } from '@ionic-native/splash-screen';
import { StatusBar } from '@ionic-native/status-bar';
import { Facebook } from '@ionic-native/facebook';
import { AngularFireModule } from 'angularfire2';
import { AngularFireAuthModule } from 'angularfire2/auth';
import { AuthService } from '../providers/auth-service';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { SignInPage } from '../pages/signin/signin';
import { SignUpPage } from '../pages/signup/signup';
export const firebaseConfig = {
apiKey: "AIzaSyA3jE_yGw17BSReFk_QMo7fuf4fSiKFW8k",
authDomain: "ionfire-df87b.firebaseapp.com",
databaseURL: "https://ionfire-df87b.firebaseio.com",
projectId: "ionfire-df87b",
storageBucket: "ionfire-df87b.appspot.com",
messagingSenderId: "783410523738"
};
@NgModule({
declarations: [
MyApp,
HomePage,
SignInPage,
SignUpPage
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp),
AngularFireModule.initializeApp(firebaseConfig),
AngularFireAuthModule
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage,
SignInPage,
SignUpPage
],
providers: [
StatusBar,
SplashScreen,
{ provide: ErrorHandler, useClass: IonicErrorHandler },
AuthService,
Facebook
]
})
export class AppModule { }

view raw

app.module4.ts

hosted with ❤ by GitHub

Primero lo importamos en la línea 6 y luego lo adicionamos a la lista de proveedores en la línea 52.

El botón

Pues es hora de adicionar el botón de entrar con Facebook, tanto en la pantalla de inicio de sesión como en la de registro respectivamente:


<ion-header>
<ion-navbar hideBackButton="true">
<ion-title>Iniciar Sesión</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<form #signInForm="ngForm" (submit)="signIn()">
<ion-list>
<ion-item>
<ion-label stacked>Correo electrónico</ion-label>
<ion-input [(ngModel)]="userModel.email" type="email" autocorrect="off" autocapitalize="none" name="email" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$"
required></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Contraseña</ion-label>
<ion-input [(ngModel)]="userModel.password" type="password" name="password" required minlength="6"></ion-input>
</ion-item>
<div padding-left padding-right padding-top>
<button ion-button [disabled]="!signInForm.form.valid" block>Entrar</button>
</div>
<div padding-left padding-right>
<p>&iquest;No tiene Cuenta de Usuario? <a (click)="signUp()">Regístrese</a>
</div>
</ion-list>
</form>
<div padding>
<div padding-bottom>Entrar con una red social:</div>
<button ion-button block (click)="signInWithFacebook()" class="facebook-btn">Entrar con Facebook</button>
</div>
</ion-content>

view raw

signin3.html

hosted with ❤ by GitHub

En la línea 31 podemos ver cómo adicionamos un div donde pusimos el botón, ya le colocamos que método queremos invocar cuando lo toquemos (el cual vamos a implementar luego) y le pusimos una clase CSS llamada facebook-btn la cual vamos a crear más adelante para darle un poco de estilo, ahora hacemos lo mismo en la página de registro:


<ion-header>
<ion-navbar>
<ion-title>Registrarse</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<form #signUpForm="ngForm" (submit)="signUp()">
<ion-list>
<ion-item>
<ion-label stacked>Correo electrónico</ion-label>
<ion-input [(ngModel)]="userModel.email" type="email" autocorrect="off" autocapitalize="none" name="email" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$"
required></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Contraseña</ion-label>
<ion-input [(ngModel)]="userModel.password" type="password" name="password" required minlength="6"></ion-input>
</ion-item>
<div padding-left padding-right padding-top>
<button ion-button [disabled]="!signUpForm.form.valid" block>Registrarse</button>
</div>
</ion-list>
</form>
<div padding>
<div padding-bottom>Entrar con una red social:</div>
<button ion-button block (click)="signInWithFacebook()" class="facebook-btn">Entrar con Facebook</button>
</div>
</ion-content>

view raw

signup3.html

hosted with ❤ by GitHub

No hay mucho que comentar sobre el código anterior…

Vamos a adicionar la clase CSS al archivo src/theme/variables.scss para poder utilizarla en varias pantallas:

.facebook-btn {
  text-transform: none !important;
  background-color: #4267b2 !important;
}

Ya tenemos todos los cambios visuales que necesitamos, si ejectuamos ionic serve podemos ver el botón en ambas pantallas, pero si lo tocamos veremos que produce un error porque no hemos implementado el método signInWithFacebook().

Servicio de autenticación

Ya nos toca refactorizar un poco el servicio de autenticación que creamos en posts anteriores el cual se encuenta en el archivo src/providers/auth-service.ts, por lo que vamos a cambiarlo por el siguiente código:


import { Injectable } from '@angular/core';
import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';
import { UserModel } from '../models/user-model';
@Injectable()
export class AuthService {
user: firebase.User;
constructor(public angularFireAuth: AngularFireAuth) {
angularFireAuth.authState.subscribe((user: firebase.User) => {
this.user = user;
});
}
get authenticated(): boolean {
return this.user != null;
}
signInWithEmailAndPassword(userModel: UserModel): firebase.Promise<any> {
return this.angularFireAuth.auth.signInWithEmailAndPassword(userModel.email, userModel.password);
}
createUserWithEmailAndPassword(userModel: UserModel): firebase.Promise<any> {
return this.angularFireAuth.auth.createUserWithEmailAndPassword(userModel.email, userModel.password);
}
signInWithFacebook(accessToken: string): firebase.Promise<any> {
const facebookCredential = firebase.auth.FacebookAuthProvider.credential(accessToken);
return this.angularFireAuth.auth.signInWithCredential(facebookCredential);
}
signInWithPopup(): firebase.Promise<any> {
return this.angularFireAuth.auth.signInWithPopup(new firebase.auth.FacebookAuthProvider());
}
signOut(): firebase.Promise<any> {
return this.angularFireAuth.auth.signOut();
}
}

Veamos qué modificaciones hicimos:

  • En la línea 4 cambiamos cómo importamos el contenido del módulo firebase/app pues ahora vamos a empezar a necesitar más clases de dicho módulo.
  • Debido a que cambiamos cómo importamos el contenido del módulo firebase/app debemos arreglar algunas referencias que perdimos pues ahora necesitamos especificar que, por ejemplo, las clases User y Promise que estabamos utilizando son del módulo firebase, por lo que a través del código ahora veremos cómo utilizamos firebase.User y firebase.Promise.
  • En la línea 30 vemos la implementación del método que nos va a permitir entrar con Facebook dado un token de autenticación, con dicho token creamos una credencial de tipo FacebookAuthProvider de Firebase la cual luego utilizamos en el método signInWithCredential() de la propiedad auth (instancia de la clase Auth de Firebase) perteneciente a angularFireAuth (servicio de AngularFire que inyectamos en posts anteriores). Necesitamos este método porque con el uso del plugin de Cordova para Facebook vamos a poder obtener el token de autenticación, ya que el mismo nos permite autenticar al usuario, luego necesitamos este método para poder “crear/autenticar” el usuario en nuestra aplicación de Firebase.
  • También implementamos el método signInWithPopup(), el cual vamos a utilizar cuando el teléfono no tenga instalada la aplicación nativa de Facebook o si decidimos usar este código como parte de nuestro sitio web, en resumen lo que hace es que utiliza el método de igual nombre de la propiedad auth el cual recibe una instancia “vacía” de FacebookAuthProvider, el API del Firebase se encarga de autenticar al usuario en Facebook, llenar la instancia de FacebookAuthProvider y “crear/autenticar” el usuario en Firebase.

Implementación de la funcionalidad de los botones

De regreso a las pantallas de inicio de sesión y registro para poder implementar el método signInWithFacebook() que dejamos pendiente, modificamos src/pages/signin/signin.ts de la siguiente manera:


import { Component } from '@angular/core';
import { NavController, LoadingController, AlertController, Platform } from 'ionic-angular';
import { Facebook } from '@ionic-native/facebook';
import { AuthService } from '../../providers/auth-service';
import { UserModel } from '../../models/user-model';
import { SignUpPage } from '../signup/signup';
import { HomePage } from '../home/home';
@Component({
selector: 'page-signin',
templateUrl: 'signin.html'
})
export class SignInPage {
userModel: UserModel;
constructor(
public navCtrl: NavController,
public loadingCtrl: LoadingController,
public alertCtrl: AlertController,
public authService: AuthService,
public platform: Platform,
public facebook: Facebook) {
this.userModel = new UserModel();
}
signIn() {
let loading = this.loadingCtrl.create({
content: 'Iniciando sesión. Por favor, espere…'
});
loading.present();
this.authService.signInWithEmailAndPassword(this.userModel).then(result => {
loading.dismiss();
this.navCtrl.setRoot(HomePage);
}).catch(error => {
loading.dismiss();
console.log(error);
this.alert('Error', 'Ha ocurrido un error inesperado. Por favor intente nuevamente.');
});
}
signInWithFacebook() {
if (this.platform.is('cordova')) {
return this.facebook.login(['email']).then(result => {
this.authService.signInWithFacebook(result.authResponse.accessToken).then(result => {
this.navCtrl.setRoot(HomePage);
});
});
} else {
return this.authService.signInWithPopup().then(result => {
this.navCtrl.setRoot(HomePage);
});
}
}
signUp() {
this.navCtrl.push(SignUpPage);
}
alert(title: string, message: string) {
let alert = this.alertCtrl.create({
title: title,
subTitle: message,
buttons: ['OK']
});
alert.present();
}
}

view raw

signin3.ts

hosted with ❤ by GitHub

  • En la línea 2 vemos cómo importamos el servicio Platform, con el cual vamos a poder determinar sobre qué entorno se está ejecutando la aplicación.
  • Importamos el wrapper de Ionic Native para el plugin de Facebook, como mismo hicimos en el módulo de la aplicación.
  • En las líneas 24 y 25 (en el constructor) inyectamos los servicios que acabamos de importar.
  • Finalmente en la línea 47, iniciamos la implementación del método signInWithFacebook(), en resumen, lo que hacemos es verificar utilizando el servicio Platform si la aplicación está ejecutandose nativamente (‘cordova’), de ser así utilizamos el plugin de Cordova para Facebook para autenticar el usuario y obtener el token y luego utilizamos el método signInWithFacebook() del servicio de autenticación authService, el cual recibe el token de autenticación de Facebook para “crear/autenticar” el usuario en Firebase. De no estar ejecutándose la aplicación en un entorno nativo utilizamos el método signInWithPopup() el cual ya explicamos anteriormente.

Les dejo de tarea hacer lo mismo en la pantalla de registro, pues es exactamente lo mismo.

Podemos ver que hay un poco de duplicación de código, lo cual vamos a aprender a resolver en un próximo post.

Ya casi estamos listos, sólo faltan algunos pasos que tienen que ver con algunas configuraciones que debemos hacer en Firebase y Facebook.

Firebase

En Firebase tenemos que activar el proveedor de autenticación de Facebook, es muy parecido a lo que hicimos cuando activamos el de “Email/Password” solo que esta vez seleccionamos el de Facebook.

Entramos a la consola de Firebase y seleccionamos el proyecto que creamos para esta aplicación, en mi caso “IonFire”, luego vamos a seleccionar el menú Authentication que se encuentra en el panel de navegación de la izquieda, seleccionamos el tab “SIGN-IN METHOD”, nos colocamos encima de la fila del proveedor de Facebook y veremos cómo al final de la fila aparece un ícono de un lápiz, al hacerle click, veremos la siguiente ventana:

Habilitando proveedor de autenticación de Facebook
Habilitando proveedor de autenticación de Facebook

Como vemos tenemos que activarlo donde dice “Enable” y colocar el “App ID” y el “App Secret” de la aplicación de Facebook que hayamos creado. En la configuración de la aplicación de Facebook tenemos que adicionar las plataformas en las que deseemos publicar nuestra aplicación: Web, Android, iOS, etc. En el caso de la Web debemos colocar la URL que nos muestra en la imagen anterior como “Site URL”:

facebook-site-url
Facebook Site URL

Hay muchas guías sobre cómo configurar una aplicación en Facebook, si tienen algún problema me dejan saber en los comentarios e intentaré ayudarles.

Y eso es todo ya podemos ejecutar nuesta aplicacion y empezar a registrar usuarios con Facebook en Firebase. Espero que les sirva de ayuda.

Si te gustó el post ayuda a compartirlo en tus redes sociales 🙂

 

One thought on “Autenticación con Facebook en Ionic con Firebase

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s