Permalink
396e762 Sep 6, 2018
1 contributor

Users who have contributed to this file

532 lines (352 sloc) 13.7 KB

Using AngularFire with Ionic 2

This document provides you a walkthrough of integrating AngularFire Authentication with Ionic2. The below setup has been tested on Windows 10, but it should be same for Mac/Linux.

Ensure that you're executing these commands as Administrator on Windows and sudo on Mac/Linux to avoid any errors.

Prerequisites

The first step is to ensure you've latest version of Node installed. You can get the latest version from here. This will install both node and npm.

After installing node, check the version by executing the following command in your prompt window.

C:\projects>node -v
v6.9.1

As of writing this document, this is the most stable version. If you're not on this version, please upgrade yourself to latest version by installing node from here.

Check your npm version by executing the following command.

C:\projects>npm -v
3.10.8

Your Application code sits on top of Ionic Framework and the Ionic Framework sits on top of Cordova.

Let's get them installed globally, so that all projects can use them.

Execute the following commands.

C:\projects>npm install -g cordova

C:\projects>npm install -g ionic

Once the above commands are executed successfully, Check the versions of cordova and ionic by executing the following commands.

C:\projects>cordova -v
6.4.0

C:\projects>ionic -v
2.1.8

These are the latest versions as of writting this document.

On successful execution of above commands, you're all set to create your Ionic app. To create your app, change into the directory where you want your app to reside and execute the following command

C:\projects> ionic start Ionic_AngularFire_Project blank --v2

The command ionic start will create the project with name "Ionic_AngularFire_Project" using "blank" template.

The --v2 flag ensures, this is a Ionic2 project.

Change to the project directory, which was just created with above command

C:\projects\Ionic_AngularFire_Project>

To start your app, execute the following command

C:\projects\Ionic_AngularFire_Project> ionic serve

If everything is installed correctly, the app should open your browser with the dev server running at following url http://localhost:8100 and will display default home page.

Stop you server by pressing "ctrl + c", if it is still running from the above step and install typings and typescript globally by executing the following commands:

Note:- typings is not required for our current application to work, but it will be helpful incase you want to bring in external libraries and extend this application.

C:\projects\Ionic_AngularFire_Project>npm install -g typings

C:\projects\Ionic_AngularFire_Project>npm install -g typescript

Check typings and typescript versions by executing following commands:

C:\projects\Ionic_AngularFire_Project>typings -v
2.0.0

C:\projects\Ionic_AngularFire_Project>tsc -v
Version 2.0.10

Configuring AngularFire and Firebase

Install AngularFire and firebase by executing the following command in your project directory

C:\projects\Ionic_AngularFire_Project>npm install AngularFire firebase --save

This should add AngularFire and firebase entry in your project's package.json file in dependencies section. Something similar

"AngularFire": "^2.0.0-beta.6",

"firebase": "^3.6.1",

Setup @NgModule

Open your project in your favourite editor and open the app.module.ts file, under src/app and add the following three entries.

  1. Import AngularFireModule at top.
  1. Define your firebaseConfig constant.
  1. Initialize your app, by calling it in the "imports" array in @NgModule

your app.module.ts file should look something like this.

import { NgModule } from '@angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';

import { AngularFireModule } from 'AngularFire';

export const firebaseConfig = {
  apiKey: "xxxxxxxxxx",
  authDomain: "your-domain-name.firebaseapp.com",
  databaseURL: "https://your-domain-name.firebaseio.com",
  storageBucket: "your-domain-name.appspot.com",
  messagingSenderId: '<your-messaging-sender-id>'
};

@NgModule({
  declarations: [
    MyApp,
    HomePage
  ],
  imports: [
    IonicModule.forRoot(MyApp),
    AngularFireModule.initializeApp(firebaseConfig)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage
  ],
  providers: []
})
export class AppModule { }

Inject AngularFireDatabase and Bind it to List

Now inject AngularFireDatabase in your component. Open your home.ts by going into src/pages/home/home.ts and make the following changes:

  1. Import "AngularFireDatabase, FirebaseListObservable" at the top of your component.
  1. Inject your AngularFireDatabase dependency in the constructor.
  1. Call the list method on the AngularFireDatabase service.

Your home.ts file should look like this.

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

import { AngularFireDatabase, FirebaseListObservable } from 'AngularFire/database';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  items: FirebaseListObservable<any[]>;

  constructor(public navCtrl: NavController, db: AngularFireDatabase) {
    this.items = db.list('/items');
  }

}

Update your home.html at src/pages/home/home.html, with following entry

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Blank
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <ion-list>
  <ion-item class="text" *ngFor="let item of items | async">
    {{item.$value}}
  </ion-item>
  </ion-list>
</ion-content>

** Run your app by executing the following command **

C:\projects\Ionic_AngularFire_Project> ionic serve

This should fetch the data from firebase.

Configuring AngularFire Auth with Ionic2

Continuing with the above example stop your server by pressing ctrl+c and go to command prompt and generate a service by executing the following command

C:\projects\Ionic_AngularFire_Project> ionic g provider AuthService

This should create the AuthService under src/providers/auth-service.ts. Update the service with the following code.

import { Observable } from 'rxjs/Observable';
import { Injectable } from '@angular/core';
import { AngularFireAuth } from 'AngularFire/auth';
// Do not import from 'firebase' as you'll lose the tree shaking benefits
import firebase from 'firebase/app';

@Injectable()
export class AuthService {
  private currentUser: firebase.User;

  constructor(public afAuth: AngularFireAuth) {
    afAuth.authState.subscribe((user: firebase.User) => this.currentUser = user);
  }

  get authenticated(): boolean {
    return this.currentUser !== null;
  }

  signInWithFacebook(): firebase.Promise<any> {
    return this.afAuth.auth.signInWithPopup(new firebase.auth.FacebookAuthProvider());
  }

  signOut(): void {
    this.afAuth.auth.signOut();
  }

  displayName(): string {
    if (this.currentUser !== null) {
      return this.currentUser.facebook.displayName;
    } else {
      return '';
    }
  }
}

Add your service in app.module.ts. Your app.module.ts should look like this

import { NgModule } from '@angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';

import { AngularFireModule } from 'AngularFire';
import { AuthService } from '../providers/auth-service';


export const firebaseConfig = {
  apiKey: "xxxxxxxxxx",
  authDomain: "your-domain-name.firebaseapp.com",
  databaseURL: "https://your-domain-name.firebaseio.com",
  storageBucket: "your-domain-name.appspot.com",
  messagingSenderId: '<your-messaging-sender-id>'
};

@NgModule({
  declarations: [
    MyApp,
    HomePage
  ],
  imports: [
    IonicModule.forRoot(MyApp),
    AngularFireModule.initializeApp(firebaseConfig)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage
  ],
  providers: [AuthService]
})
export class AppModule { }

Update your home.html to add a login button. Your home.html should look like this

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Blank
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <ion-list>
  <ion-item class="text" *ngFor="let item of items | async">
    {{item | json}}
  </ion-item>
  </ion-list>

  <button ion-button outline (click)="signInWithFacebook()">Facebook</button>
</ion-content>

and finally, add the corresponding click handlers in home.ts as follows. Also, ensure the AuthService is injected in the constructor. Your home.ts should look like this

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

import { AuthService } from '../../providers/auth-service';
import { AngularFireDatabase, FirebaseListObservable } from 'AngularFire/database';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  items: FirebaseListObservable<any[]>;

  constructor(public navCtrl: NavController, db: AngularFireDatabase, private _auth: AuthService) {
    this.items = db.list('/items');
  }

  signInWithFacebook(): void {
    this._auth.signInWithFacebook()
      .then(() => this.onSignInSuccess());
  }

  private onSignInSuccess(): void {
    console.log("Facebook display name ",this._auth.displayName());
  }

}

Now run your app and if everything is configured correctly, you should be able to click on the login button in your app, which should open the facebook pop-up.

Once you authenticate yourself, you should see your Facebook display name in console.

You can try redirecting yourself to another page to grab additional details from Facebook.

Running our application on mobile phone.

Ensure you've the platform added to your project. If not add the platform by executing the following command.


C:\projects\Ionic_AngularFire_Project>ionic platform add android

This adds android platform for your project. Replace android with ios, if you're on Mac book or add both. The generic command is ionic platform add <platform-name>

Now, let's try to run the app in browser. Execute the command


C:\projects\Ionic_AngularFire_Project> ionic run android

This should run the app on your mobile phone. Now click on the Facebook button and you'll notice the button doesn't work anymore. This is because the code written so far is good for running our application in browsers, but when running the application on mobile phones, we need to have access to Native Mobile API's, which are provided by Cordova Plugins.

We can access these cordova plugins, using Ionic Native, which are nothing but wrappers for cordova plugins.

List of all Ionic Native API's for cordova plugins can be found here.

Let's look at configuring and installing facebook plugin here. Ensure you follow the steps correctly to configure your app.

Once you create your app and make a note of your App ID, go to command prompt in your project directory and execute the following command

C:\projects\Ionic_AngularFire_Project>
ionic plugin add cordova-plugin-facebook4 --save --variable APP_ID="123456789" --variable APP_NAME="myApp"

Replace App ID with your app id from portal and provide your app name.

This will install the cordova plugin for facebook.

Add the platform to your facebook portal as mentioned in the document here.

Now import the Platform and Facebook objects in your auth-service.ts

import { Platform } from 'ionic-angular';
import { Facebook } from 'ionic-native';

and update the signInWithFacebook() method.

your auth-service.ts code should look like this.

import { Observable } from 'rxjs/Observable';
import { Injectable } from '@angular/core';
import { AngularFireAuth } from 'AngularFire/auth';
// Do not import from 'firebase' as you'll lose the tree shaking benefits
import firebase from 'firebase/app';

import { Platform } from 'ionic-angular';
import { Facebook } from 'ionic-native';

@Injectable()
export class AuthService {
  private currentUser: firebase.User;

  constructor(public afAuth: AngularFireAuth) {
    afAuth.authState.subscribe((user: firebase.User) => this.currentUser = user);
  }

  get authenticated(): boolean {
    return this.currentUser !== null;
  }

  signInWithFacebook(): firebase.Promise<any> {
    if (this.platform.is('cordova')) {
      return Facebook.login(['email', 'public_profile']).then(res => {
        const facebookCredential = firebase.auth.FacebookAuthProvider.credential(res.authResponse.accessToken);
        return this.afAuth.auth.signInWithCredential(facebookCredential);
      });
    } else {
      return this.afAuth.auth.signInWithPopup(new firebase.auth.FacebookAuthProvider());
    }

  }

  signOut(): void {
    this.afAuth.auth.signOut();
  }

  displayName(): string {
    if (this.currentUser !== null) {
      return this.currentUser.facebook.displayName;
    } else {
      return '';
    }
  }
}

Verfiy your app is running in browser by executing the following command


C:\projects\Ionic_AngularFire_Project>ionic serve

Everything should work. Now trying running the app on your android phone


C:\projects\Ionic_AngularFire_Project> ionic run android

Once the App launches click on the Facebook login button and it should open up the native facebook app for authentication and once your enter credentials and gets succesfully authenticated, it should redirect you back to the home page.