ChrizTalk

Ionic 3 and Firebase Facebook authentication using AngularFire2

October 19, 2017ChrizFirebase, IonicNo Comments
If you like it, please share it:

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.

Facebook dashbaord app id and app secret

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

Firebase authentication Facebook provider

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

Facebook login product dashboard

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.

Facebook Login client oauth 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.

Facebook app development mode

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…

If you like it, please share it:
Previous Post Ionic 3 and Firebase authentication using AngularFire2

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • Ionic 3 and Firebase Facebook authentication using AngularFire2
  • Ionic 3 and Firebase authentication using AngularFire2
  • Ionic 3, Firebase and AngularFire2
  • Ionic 2 and Font Awesome using Sass
  • Using Google Fonts in Ionic 2

My Ionic 2 Theme

Please have a look at my new Ionic 2 theme.

&copy 2016 ChrizTalk