This post is based on my previous post Ionic 3 and Firebase authentication using AngularFire2.
You can download the code on GitHub at https://github.com/henkie14/ionic3Firebase. Make sure you change the Firebase configuration in the app.module.ts file.
In this post I will continue working on the project above and add native Facebook authentication to the Ionic app.
The first thing you will have to do is to create a new Facebook App in the Facebook developer portal, install the cordova Facebook plugin and configure your Facebook app for Android and/or iOS.
There is a nice installation guide on http://ionicframework.com/docs/v2/native/facebook/.
Make sure you do the installation up to the Events chapter and you are good to go.
For future use make sure you can find the Facebook App ID and App secret you will need them in a later stage.
Eventually you should have an APP_ID, an APP_NAME and the App secret.
Now you can run the following command. (Add –save if you want the plugin and configuration to be stored in your config.xml).
$ionic cordova plugin add cordova-plugin-facebook4 --variable APP_ID="yourAppId" --variable APP_NAME="yourAppName" --save $npm install --save @ionic-native/facebook
Register the Facebook component to 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 { MyApp } from './app.component'; import { HomePage } from '../pages/home/home'; import { SignupPage } from '../pages/signup/signup'; import { AngularFireModule } from 'angularfire2'; import { AngularFireAuthModule } from 'angularfire2/auth'; import { AuthProvider } from '../providers/auth-provider'; import { Facebook } from '@ionic-native/facebook'; //Added Facebook export const firebaseConfig = { apiKey: '*****', authDomain: '*****', databaseURL: '*****', storageBucket: '*****', messagingSenderId: '*****' }; @NgModule({ declarations: [ MyApp, HomePage, SignupPage, ResetPasswordPage ], imports: [ IonicModule.forRoot(MyApp), BrowserModule, AngularFireModule.initializeApp(firebaseConfig), AngularFireAuthModule ], bootstrap: [IonicApp], entryComponents: [ MyApp, HomePage, SignupPage, ResetPasswordPage ], providers: [ StatusBar, SplashScreen, {provide: ErrorHandler, useClass: IonicErrorHandler}, AuthProvider, Facebook //Added Facebook ] }) export class AppModule {}
Let’s add a Facebook login button to the home page, open up your home.html and change it like this:
<ion-header> <ion-navbar> <ion-title> Ionic2Firebase </ion-title> </ion-navbar> </ion-header> <ion-content padding> <ion-title>Login</ion-title> <ion-row> <ion-item> <div *ngIf="auth.authState">current user is {{auth.currentUser}}</div> </ion-item> </ion-row> <form [formGroup]="loginForm" novalidate> <ion-row> <ion-item> <ion-label for="email"></ion-label> <ion-input type="email" value="" placeholder="Email" formControlName="email"></ion-input> </ion-item> </ion-row> <ion-row> <ion-item> <ion-label for="password"></ion-label> <ion-input type="password" placeholder="Password" formControlName="password"></ion-input> </ion-item> </ion-row> </form> <ion-row> <button (click)="login()" ion-button block>Log in</button> </ion-row> <ion-row> <button [navPush]="signupPage" ion-button block>Sign up</button> </ion-row> <!--new link to sign up page--> <ion-row> <button [navPush]="resetPasswordPage" ion-button block>Reset password</button> </ion-row> <ion-row> <button (click)="logout()" ion-button block>Log out</button> </ion-row> <ion-row> <button (click)="loginWithFacebook()" ion-button block>Facebook login</button> </ion-row> </ion-content>
And add the loginWithFacebook method to home.ts.
import { Component } from '@angular/core'; import { FormGroup, FormBuilder, Validators, AbstractControl } from '@angular/forms'; import { NavController } from 'ionic-angular'; import { AuthProvider } from '../../providers/auth-provider'; import { SignupPage } from '../signup/signup' import { ResetPasswordPage } from '../reset-password/reset-password' @Component({ selector: 'page-home', templateUrl: 'home.html' }) export class HomePage { loginForm: FormGroup; email: AbstractControl; password: AbstractControl; error: any; signupPage = SignupPage; resetPasswordPage = ResetPasswordPage constructor(private navCtrl: NavController, private fb: FormBuilder, private auth: AuthProvider) { this.loginForm = this.fb.group({ 'email': ['', Validators.compose([Validators.required, Validators.pattern(/[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/)])], 'password': ['', Validators.compose([Validators.required, Validators.minLength(1)])] }); this.email = this.loginForm.controls['email']; this.password = this.loginForm.controls['password']; } loginWithFacebook(): void{ this.auth.loginWithFacebook().subscribe((success) => { console.log(success); }, err => { console.log(err); }); } login(): void { if(this.loginForm.valid) { var credentials = ({email: this.email.value, password: this.password.value}); this.auth.loginWithEmail(credentials).subscribe(data => { alert('login succeeded'); console.log(data); }, error=>{ console.log(error); if (error.code == 'auth/user-not-found') { alert('User not found'); } }); } } logout(): void { this.auth.logout(); } }
Last part is the implementation on the authorization provider. Change auth-provider.ts like this:
import { Injectable, EventEmitter, Inject } from '@angular/core'; import { AngularFireAuth } from 'angularfire2/auth'; import { Observable } from "rxjs/Observable"; import { Platform } from 'ionic-angular'; import { Facebook } from '@ionic-native/facebook'; //Added Facebook import * as firebase from 'firebase/app'; //Changed firebase/app @Injectable() export class AuthProvider { constructor(private af: AngularFireAuth, private fb: Facebook, private platform: Platform) { } //Added injectors loginWithFacebook() { return Observable.create(observer => { if (this.platform.is('cordova')) { return this.fb.login(['email', 'public_profile']).then(res => { const facebookCredential = firebase.auth.FacebookAuthProvider.credential(res.authResponse.accessToken); this.af.app.auth().signInWithCredential(facebookCredential).then(()=>{ observer.next(); }).catch(error => { //console.log(error); observer.error(error); }); }); } else { return this.af.auth.signInWithPopup(new firebase.auth.FacebookAuthProvider()).then(()=>{ observer.next(); }).catch(error => { //console.log(error); observer.error(error); }); } }); } loginWithEmail(credentials) { return Observable.create(observer => { this.af.auth.login(credentials, { provider: AuthProviders.Password, method: AuthMethods.Password }).then((authData) => { //console.log(authData); observer.next(authData); }).catch((error) => { observer.error(error); }); }); } registerUser(credentials: any) { return Observable.create(observer => { this.af.auth.createUser(credentials).then(authData => { //authData.auth.updateProfile({displayName: credentials.displayName, photoURL: credentials.photoUrl}); //set name and photo observer.next(authData); }).catch(error => { //console.log(error); observer.error(error); }); }); } resetPassword(emailAddress:string){ return Observable.create(observer => { this.firebase.auth().sendPasswordResetEmail(emailAddress).then(function(success) { //console.log('email sent', success); observer.next(success); }, function(error) { //console.log('error sending email',error); observer.error(error); }); }); } logout() { this.af.auth.logout(); } get currentUser():string{ return this.authState?this.authState.auth.email:''; } }
There’s a lot going on here, let me explain.
There’s an import of Platform, that’s being used to check on what platform the app is running, based on the platform we will call the native Facebook login or a pop-up.
The Facebook import is used for calling the native Facebook plugin.
Ok, let’s run the application to see if it’s working. First test it in your browser.
$ionic serve
When you try to login by Facebook you will see the following error:
The given sign-in provider is disabled for this Firebase project. Enable it in the Firebase console, under the sign-in method tab of the Auth section.
So let’s go to the Firebase console again at https://console.firebase.google.com and select your project.
Next select Authentication on the left hand side and click the tab ‘Sign in method’.
Click Facebook and enable it. Fill in you App Id and App secret, if you didn’t already write them down you can get them from your Facebook developer portal on the dashboard page (https://developers.facebook.com).
Make sure you copy the OAuth redirect URI and click the save button.
Now you should go back to the Facebook developer portal and click ‘+ add product’ on the lef hand side and select ‘Facebook Login’.
Next click ‘settings’ below Facebook Login on the left hand side and fill in the Auth redirect URI you’ve copied from the Firebase Facebook provider settings.
Let’s test it again in your browser.
$ionic serve
When you click the Facebook login button you should see a popup where you can connect with your Facebook account and when you login, it should show the corresponding email address as the current user.
You can also check the users tab on the authentication menu in the Firebase console to see all registered users and their provider.
Now let’s try it on android to see if the native Facebook functionality is working. Connect you Android phone and run the following commands.
$ionic platform add android $ionic run android
Okay, when trying to login by Facebook you will see a native popup, but with this message: “Facebook test error in development mode.”
This can be fixed by going to the Facebook developer portal again and after selecting your project, you should select ‘App Review’ from the menu on the left and make the app public.
If you see an error about a missing android hash key, you should create one, for debug purposes run this:
$keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore |openssl sha1 -binary | openssl base64
And configure it in your Facebook configuration.
This should be all!
If things don’t seem to work or you see the following Firebase error: auth/network-request-failed. Try this:
$ionic platform rm android $ionic platform add android
You can try it out on iOS by connecting you iOS device and run:
$ionic platform add ios $ionic run ios
Please leave a message if you got it working or not or things aren’t clear or whatever 🙂
Next is native Google login…
1 comment. Leave new
Can I use it for Progressive web application also