Documente Academic
Documente Profesional
Documente Cultură
0. Prerequisites
Before you start installing AngularFire2, make sure you have latest version of angular-cli
installed. To verify run the command ng -v and ensure you see angular-cli: 1.x.x-
beta.xx. The lowest compatible version is 1.x.x-beta.14.
If not, you may need to do the following:
The Angular CLI's new command will set up the latest Angular build in a new project
structure.
Now that you have a new project setup, install AngularFire2 and Firebase from npm.
@NgModule({
imports: [
BrowserModule,
AngularFireModule.initializeApp(environment.firebase)
],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule {}
AngularFireAuthModule
AngularFireDatabaseModule
AngularFireStorageModule (Future release)
AngularFireMessagingModule (Future release)
For example if you application was using both Firebase authentication and the Firebase
database you would add:
@NgModule({
imports: [
BrowserModule,
AngularFireModule.initializeApp(environment.firebase, 'my-app-name'), // imports
firebase/app needed for everything
AngularFireDatabaseModule, // imports firebase/database, only needed for database
features
AngularFireAuthModule, // imports firebase/auth, only needed for auth features
],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule {}
7. Inject AngularFireDatabase
Open /src/app/app.component.ts, and make sure to modify/delete any tests to get the
sample working (tests are still important, you know):
import { Component } from '@angular/core';
import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css']
})
export class AppComponent {
constructor(db: AngularFireDatabase) {
}
}
8. Bind to a list
In /src/app/app.component.ts:
import { Component } from '@angular/core';
import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css']
})
export class AppComponent {
items: FirebaseListObservable<any[]>;
constructor(db: AngularFireDatabase) {
this.items = db.list('/items');
}
}
Open /src/app/app.component.html:
<ul>
<li class="text" *ngFor="let item of items | async">
{{item.$value}}
</li>
</ul>
Troubleshooting
// ADD THIS
"types": [
"firebase"
]
}
}
2. Cannot find name 'require' (This is just a temporary workaround for the Angular
CLI).
If you run into this error while trying to invoke ng serve, open src/typings.d.ts and add
the following two entries as follows:
declare var require: any;
declare var module: any;
2. Retrieving data as objects
AngularFire2 synchronizes data as objects using the FirebaseObjectObservable.
The FirebaseObjectObservable is not created by itself, but through
the AngularFireDatabase service. The guide below demonstrates how to retrieve, save,
and remove data as objects.
Make sure you have bootstrapped your application for AngularFire2. See the
Installation guide for bootstrap setup.
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css']
})
export class AppComponent {
items: FirebaseListObservable<any[]>;
constructor(db: AngularFireDatabase) {
this.items = db.list('items');
}
}
In this section, we're going to modify the /src/app/app.component.ts to retreive data as
object.
1. Relative URL
2. Absolute URL
Retrieve data
To get the object in realtime, create an object binding as a property of your component
or service. Then in your template, you can use the async pipe to unwrap the binding.
Replace the FirebaseListObservable to FirebaseObjectObservable in
your /src/app/app.component.ts as below. Also notice the templateUrl changed to inline
template below:
import { Component } from '@angular/core';
import { AngularFireDatabase, FirebaseObjectObservable } from
'angularfire2/database';
@Component({
selector: 'app-root',
template: `
<h1>{{ (item | async)?.name }}</h1>
`,
})
export class AppComponent {
item: FirebaseObjectObservable<any>;
constructor(db: AngularFireDatabase) {
this.item = db.object('/item');
}
}
Saving data
API Summary
The table below highlights some of the common methods on
the FirebaseObjectObservable.
method
Replaces the current value in the database with the new value specified as the paramet
set(value: any) a destructive update, because it deletes everything currently in place and saves the ne
update(value: Updates the current value with in the database with the new value specified as the par
Object) a non-destructive update, because it only updates the values specified.
remove() Deletes all data present at that location. Same as calling set(null).
Returning promises
Each data operation method in the table above returns a promise. However, you should
rarely need to use the completion promise to indicate success, because the realtime
database keeps the object in sync.
The promise can be useful to chain multiple operations, catching possible errors from
security rules denials, or for debugging.
Saving data
Use the set() method for destructive updates.
const itemObservable = db.object('/item');
itemObservable.set({ name: 'new name!'});
Updating data
Use the update() method for non-destructive updates.
const itemObservable = db.object('/item');
itemObservable.update({ age: newAge });
Only objects are allowed for updates, not primitives. This is because using an update
with a primitive is the exact same as doing a .set() with a primitive.
Deleting data
Use the remove() method to remove data at the object's location.
const itemObservable = db.object('/item');
itemObservable.remove();
Example app:
@Component({
selector: 'app-root',
template: `
<h1>{{ item | async | json }}</h1>
<input type="text" #newname placeholder="Name" />
<input type="text" #newsize placeholder="Size" />
<br />
<button (click)="save(newname.value)">Set Name</button>
<button (click)="update(newsize.value)">Update Size</button>
<button (click)="delete()">Delete</button>
`,
})
export class AppComponent {
item: FirebaseObjectObservable<any>;
constructor(db: AngularFireDatabase) {
this.item = db.object('/item');
}
save(newName: string) {
this.item.set({ name: newName });
}
update(newSize: string) {
this.item.update({ size: newSize });
}
delete() {
this.item.remove();
}
}
Data retrieved from the object binding contains special properties retrieved from the
unwrapped Firebase DataSnapshot.
property
$key The key for each record. This is equivalent to each record's path in our database as it would be re
If the data for this child node is a primitive (number, string, or boolean), then the record itself wil
$value
primitive value will be stored under $value and can be changed and saved like any other field.
AngularFire2 unwraps the Firebase DataSnapshot by default, but you can get the data as
the original snapshot by specifying the preserveSnapshot option.
this.item = db.object('/item', { preserveSnapshot: true });
this.item.subscribe(snapshot => {
console.log(snapshot.key)
console.log(snapshot.val())
});
Querying?
Make sure you have bootstrapped your application for AngularFire2. See the
Installation guide for bootstrap setup.
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css']
})
export class AppComponent {
constructor(db: AngularFireDatabase) {
}
}
In this section, we're going to modify the /src/app/app.component.ts to retreive data as
list, but before that let's look at ways around how to bind to a list.
1. Relative URL
2. Absolute URL
3. Query
// relative URL, uses the database url provided in bootstrap
const relative = db.list('/items');
// absolute URL
const absolute = db.list('https://<your-app>.firebaseio.com/items');
// query
const queryList = db.list('/items', {
query: {
limitToLast: 10,
orderByKey: true
}
});
Retrieve data
To get the list in realtime, create a list binding as a property of your component or
service. Then in your template, you can use the async pipe to unwrap the binding.
Update /src/app/app.component.ts to import FirebaseListObservable from angularfire2
and iterate thru the list once data is retrieved. Also note the change in
attribute templateUrl to inline template below.
import { Component } from '@angular/core';
import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database';
@Component({
selector: 'app-root',
template: `
<ul>
<li *ngFor="let item of items | async">
{{ item | json }}
</li>
</ul>
`,
})
export class AppComponent {
items: FirebaseListObservable<any>;
constructor(db: AngularFireDatabase) {
this.items = db.list('/items');
}
}
Saving data
API Summary
The table below highlights some of the common methods on
the FirebaseListObservable.
method
push(value: any) Creates a new record on the list, using the Realtime Database's push-
remove(key: string?) Deletes the item by key. If no parameter is provided, the entire list wil
Returning promises
Each data operation method in the table above returns a promise. However, you should
rarely need to use the completion promise to indicate success, because the realtime
database keeps the list in sync.
The promise can be useful to chain multiple operations, catching possible errors from
security rules denials, or for debugging.
If you omit the key parameter from .remove() it deletes the entire list.
const items = db.list('/items');
items.remove();
Example app
@Component({
selector: 'app-root',
template: `
<ul>
<li *ngFor="let item of items | async">
<input type="text" #updatetext [value]="item.text" />
<button (click)="updateItem(item.$key, updatetext.value)">Update</button>
<button (click)="deleteItem(item.$key)">Delete</button>
</li>
</ul>
<input type="text" #newitem />
<button (click)="addItem(newitem.value)">Add</button>
<button (click)="deleteEverything()">Delete All</button>
`,
})
export class AppComponent {
items: FirebaseListObservable<any>;
constructor(db: AngularFireDatabase) {
this.items = db.list('/messages');
}
addItem(newName: string) {
this.items.push({ text: newName });
}
updateItem(key: string, newText: string) {
this.items.update(key, { text: newText });
}
deleteItem(key: string) {
this.items.remove(key);
}
deleteEverything() {
this.items.remove();
}
}
Data retrieved from the object binding contains special properties retrieved from the
unwrapped Firebase DataSnapshot.
property
$key The key for each record. This is equivalent to each record's path in our database as it would be re
If the data for this child node is a primitive (number, string, or boolean), then the record itself wil
$value
primitive value will be stored under $value and can be changed and saved like any other field.
AngularFire2 unwraps the Firebase DataSnapshot by default, but you can get the data as
the original snapshot by specifying the preserveSnapshot option.
this.items = db.list('/items', { preserveSnapshot: true });
this.items
.subscribe(snapshots => {
snapshots.forEach(snapshot => {
console.log(snapshot.key)
console.log(snapshot.val())
});
})
4. Querying lists
Querying is a killer feature of AngularFire2. You can specify query values as observables,
and when those observables emit new values, the query is automatically re-run.
method purpose
limitToFirst Sets the maximum number of items to return from the beginning of the ordered list of r
limitToLast Sets the maximum number of items to return from the end of the ordered list of results.
startAt 1 Return items greater than or equal to the specified key or value, depending on the order
endAt 1 Return items less than or equal to the specified key or value, depending on the order-by
1The Firebase SDK supports an optional key parameter for startAt, endAt,
and equalTo when ordering by child, value, or priority. You can specify the key parameter
using an object literal that contains the value and the key. For example: startAt: {
value: 'some-value', key: 'some-key' }.
Queries can only be ordered by one method. This means you can only
specify orderByChild, orderByKey, orderByPriority, or orderByValue.
// WARNING: Do not copy and paste. This will not work!
const queryObservable = db.list('/items', {
query: {
orderByChild: 'size',
equalTo: 'large',
orderByKey: true,
}
});
You can only use limitToFirst or limitToLast, but not both in combination.
// WARNING: Do not copy and paste. This will not work!
const queryObservable = db.list('/items', {
query: {
limitToFirst: 10,
limitToLast: 100,
}
});
Rather than specifying regular values, observables can be used to dynamically re-run
queries when the observable emits a new value.
An RxJS Subject is imported below. A Subject is like an Observable, but can multicast to
many Observers. Subjects are like EventEmitters: they maintain a registry of many
listeners. See, What is a Subject for more information.
// subscribe to changes
queryObservable.subscribe(queriedItems => {
console.log(queriedItems);
});
// trigger the query
subject.next('large');
@Component({
selector: 'app-root',
template: `
<ul>
<li *ngFor="let item of items | async">
{{ item.text }}
</li>
</ul>
<div>
<h4>Filter by size</h4>
<button (click)="filterBy('small')">Small</button>
<button (click)="filterBy('medium')">Medium</button>
<button (click)="filterBy('large')">Large</button>
</div>
`,
})
export class AppComponent {
items: FirebaseListObservable<any[]>;
sizeSubject: Subject<any>;
constructor(db: AngularFireDatabase) {
this.sizeSubject = new Subject();
this.items = db.list('/items', {
query: {
orderByChild: 'size',
equalTo: this.sizeSubject
}
});
}
filterBy(size: string) {
this.sizeSubject.next(size);
}
}
+To run the above example as is, you need to have sample data in you firebase
database with the following structure:"
-|items
-|item1
-|size: small
-|text: sample small text
-|item2
-|size: medium
-|text: sample medium text
-|item3
-|size: large
-|text: sample large text
5. User authentication
AngularFireAuth.authState provides you an Observable<firebase.User> to monitor your
application's authentication State.
AngularFireAuth.auth returns an initialized firebase.auth.Auth instance, allowing you to
log users in, out, etc. See the Firebase docs for more information on what methods are
availabile.
Example app:
@Component({
selector: 'app-root',
template: `
<div> {{ (user | async)?.uid }} </div>
<button (click)="login()">Login</button>
<button (click)="logout()">Logout</button>
`,
})
export class AppComponent {
user: Observable<firebase.User>;
login() {
this.afAuth.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
}
logout() {
this.afAuth.auth.signOut();
}
}
Cordova
Learn how to setup Firebase Authentication with Cordova in the Firebase Guides.
Using AngularFire2 with Ionic 2
This document provides you a walkthrough of integrating AngularFire2 Authentication
with Ionic2. The below setup has been tested on Windows 10, but it should be same for
Mac/Linux.
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 writting 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.
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.
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 2 app.
To create your app, change into the directory where you want your app to reside and
execute the following command
C:\projects\Ionic_AngularFire2_Project>
To start your app, execute the following command
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_AngularFire2_Project>typings -v
2.0.0
C:\projects\Ionic_AngularFire2_Project>tsc -v
Version 2.0.10
"angularfire2": "^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.
@NgModule({
declarations: [
MyApp,
HomePage
],
imports: [
IonicModule.forRoot(MyApp),
AngularFireModule.initializeApp(firebaseConfig)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage
],
providers: []
})
export class AppModule { }
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
items: FirebaseListObservable<any[]>;
}
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 **
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_AngularFire2_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 'angularfire2/auth';
// Do not import from 'firebase' as you'll lose the tree shaking benefits
import * as firebase from 'firebase/app';
@Injectable()
export class AuthService {
private authState: Observable<firebase.User>;
private currentUser: firebase.User;
signInWithFacebook(): firebase.Promise<FirebaseAuthState> {
return this.afAuth.auth.signInWithPopup(new
firebase.auth.FacebookAuthProvider());
}
signOut(): void {
this.afAuth.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 'angularfire2';
import { AuthService } from '../providers/auth-service';
@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>
items: FirebaseListObservable<any[]>;
signInWithFacebook(): void {
this._auth.signInWithFacebook()
.then(() => this.onSignInSuccess());
}
}
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.
Ensure you've the platform added to your project. If not add the platform by executing
the following command.
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
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 Corodova Plugins.
We can access these corodva plugins, using Ionic Native, which are nothing but
wrappers for cordova plugins.
List of all Ionic Native API's for corodova 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_AngularFire2_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.
Add the platform to your facebook portal as mentioned in the document here.
@Injectable()
export class AuthService {
private authState: Observable<firebase.User>;
private currentUser: firebase.User;
signInWithFacebook(): firebase.Promise<FirebaseAuthState> {
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.signOut();
}
displayName(): string {
if (this.currentUser !== null) {
return this.currentUser.facebook.displayName;
} else {
return '';
}
}
}
C:\projects\Ionic_AngularFire2_Project>ionic serve
Everything should work. Now trying running the app on your android phone
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.
Using AngularFire2 with Ionic 3-Angular
4
This tutorial provides a walkthrough of integrating AngularFire2 Authentication with
Ionic3/Angular4. The below setup has been tested on Windows 10, but it should be
same for Mac/Linux.
Note: - If you're working with Ionic2 and Angular2.0, then you should refer to Auth-
with-Ionic2 tutorial here
This tutorial uses Facebook as the sign-in provider. After completion of this tutorial, you
should be able to configure other sign-in providers like Twitter, Google on your own.
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.10.2
As of writting 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.
C:\projects>npm -v
3.10.10
Install the Angular CLI, which will be used to build our Angular project and install
Angular version 4 later.
C:\projects>ng -v
@angular/cli: 1.0.0
node: 6.10.2
os: win32 x64
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.
C:\projects>cordova -v
6.4.0
C:\projects>ionic -v
2.2.3
These are the latest versions as of writting this document.
On successful execution of above commands, you're all set to create your app with Ionic
3 framework.
To create your app, change into the directory where you want your app to reside and
execute the following command
C:\projects\auth-ng4-ionic3-af2>ionic info
Cordova CLI: 6.4.0
Ionic Framework Version: 3.1.1
Ionic CLI Version: 2.2.3
Ionic App Lib Version: 2.2.1
Ionic App Scripts Version: 1.3.7
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Windows 10
Node Version: v6.10.2
Xcode version: Not installed
You need to ensure you've got Ionic Framework Version 3, as shown above.
Alternatively you can open package.json to ensure you've got the following angualr and
Ionic versions
"dependencies": {
"@angular/common": "4.0.2",
"@angular/compiler": "4.0.2",
"@angular/compiler-cli": "4.0.2",
"@angular/core": "4.0.2",
"@angular/forms": "4.0.2",
"@angular/http": "4.0.2",
"@angular/platform-browser": "4.0.2",
"@angular/platform-browser-dynamic": "4.0.2",
"@ionic-native/core": "3.6.1",
"@ionic-native/splash-screen": "3.6.1",
"@ionic-native/status-bar": "3.6.1",
"@ionic/storage": "2.0.1",
"ionic-angular": "3.1.1",
"ionicons": "3.0.0",
"rxjs": "5.1.1",
"sw-toolbox": "3.4.0",
"zone.js": "^0.8.10"
},
"devDependencies": {
"@ionic/app-scripts": "1.3.7",
"typescript": "~2.2.1"
}
If not, replace them to match above. These are the latest as of writing this tutorial.
"angularfire2": "^4.0.0-rc.0",
"firebase": "^3.9.0",
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 and AngularFireDatabaseModule at top.
@NgModule({
declarations: [
MyApp,
HomePage
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp),
AngularFireModule.initializeApp(firebaseConfig),
AngularFireDatabaseModule
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage
],
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler}
]
})
export class AppModule {}
Inject AngularFire 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:
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
items: FirebaseListObservable<any[]>;
}
*Ensure you've items node in your database with some primitive data.
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
Once the App is created, get the App ID and App Secret from the dashboard and come
back to Firebase Console.
1. Login to Firebase Console and click on the Authentication section on the left hand side
of the menu.
2. Click on Sign-In Method tab and click on Facebook under Sign-In Providers.
3. Paste the App ID and App Secret copied from Facebook dashboard here.
4. Next copy the "OAuth redirect URI" from Firebase console. We need to go back and add
it in Facebook dashboard.
This URI is important, since it tells facebook, where to redirect a user, once he is
successfully authenticated.
5. Click the Save button and come back to the facebook dashboard.
6. Ensure you see Facebook Login under products section, if not add it via the Add Product
Button.
7. Once you see Facebook Login under products, click on the button to go to settings and
there you should see "Valid OAuth redirect URIs" input field.
8. Enter the URI copied from Firebase Console and click on Save Changes.
That's it. This will ensure Facebook and Firebase are able to talk to each other.
As we were able to fetch data from Firebase database in the above step, let's focus
on authentication below, by removing calls to fetch data.
Let's add the following two buttons in our home.html
The home.html should look like below
<ion-header>
<ion-navbar>
<ion-title>
Auth with Ionic 3
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<button ion-button outline (click)="signInWithFacebook()">Login</button>
<button ion-button outline (click)="signOut()">Logout</button>
</ion-content>
Let's update the home.ts to add the corresponding methods:
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
signInWithFacebook() {
this.afAuth.auth
.signInWithPopup(new firebase.auth.FacebookAuthProvider())
.then(res => console.log(res));
}
signOut() {
this.afAuth.auth.signOut();
}
}
Note the import of firebase from firebase/app, to take advantage of the tree-
shaking
Run the app and click on the Login Button, you should see a pop-up asking you to enter
username and password for facebook to authenticate. Once authenticated, you should
see the response from Facebook in console window.
Inspect the Object in the console, under user property, you should see all the attributes
and we're going to use two of them, next.
Let's get the displayName from the user property, which we just saw on the console to be
rendered on the screen. The AngularFireAuth has an authState property, which returns an
observable, let's subcribe it to get notified everytime the Authentication state changes.
Add class property displayName and subscribe to the AngularFireAuth.authState property
in the constructor. Also add the property in our template to render them on screen.
Your home.ts should look as follows:
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
displayName;
signInWithFacebook() {
this.afAuth.auth
.signInWithPopup(new firebase.auth.FacebookAuthProvider())
.then(res => console.log(res));
}
signOut() {
this.afAuth.auth.signOut();
}
<h1>Hello {{displayName}}</h1>
Once you authenticate yourself, you should see your Facebook display name on your
screen. Click the Logout button, which will make the AuthState to null and you should
see the difference on your screen.
You can try redirecting yourself to another page to grab additional details from
Facebook and experiement on your own.
Ensure you've the platform added to your project. If not add the platform by executing
the following command.
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
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 Corodova Plugins.
We can access these corodva plugins, using Ionic Native, which are nothing but
wrappers for cordova plugins.
List of all Ionic Native API's for corodova 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.
Login to facebook dashboard here, go to your App and make a note of your App ID.
Next go to command prompt in your project directory and execute the following
command by replacing the APP_ID with your App Id and APP_NAME with your App Name.
C:\projects\auth-ng4-ionic3-af2>
ionic plugin add cordova-plugin-facebook4 --variable APP_ID="123456789" --variable
APP_NAME="myApplication" --save
This should add following entry in your config.xml, located at the root of your project.
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
displayName;
signInWithFacebook() {
if (this.platform.is('cordova')) {
return this.fb.login(['email', 'public_profile']).then(res => {
const facebookCredential =
firebase.auth.FacebookAuthProvider.credential(res.authResponse.accessToken);
return firebase.auth().signInWithCredential(facebookCredential);
})
}
else {
return this.afAuth.auth
.signInWithPopup(new firebase.auth.FacebookAuthProvider())
.then(res => console.log(res));
}
}
signOut() {
this.afAuth.auth.signOut();
}
You'll also need to add the "Facebook" object in the provider section in app.module.ts.
@NgModule({
declarations: [
MyApp,
HomePage
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp),
AngularFireModule.initializeApp(firebaseConfig),
AngularFireDatabaseModule,
AngularFireAuthModule
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage
],
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler},
Facebook
]
})
export class AppModule {}
C:\projects\auth-ng4-ionic3-af2>ionic serve
Everything should work. Now trying running the app on your android phone
If the above doesn't works then the below steps should help. Please ensure all the
commands are executed as an Administrator.
Steps:
3) Install Angular-CLI
npm install -g angular-cli
Post this installation, follow the installation guide to install AngularFire2 and
everything should work as expected.
Note:-
When you start your app using "ng serve" in the console, you might still see the below
errors. Despite these errors, the application should work as expected and should be able
to talk to Firebase.
ERROR in [default]
C:\angularFire2Test\node_modules\angularfire2\interfaces.d.ts:12:34
Cannot find namespace 'firebase'.
AngularFireModule
AngularFireDatabaseModule
AngularFireAuthModule
user: Observable<firebase.User>;
constructor(afAuth: AngularFireAuth) {
this.user = afAuth.authState; // only triggered on sign-in/out (for old behavior
use .idToken)
}
AngularFire2 exposes the raw Firebase Auth object via AngularFireAuth.auth. For actions
like login, logout, user creation, etc. you should use the methods available
to firebase.auth.Auth.
While convenient, the pre-configured login feature added unneeded
complexity. AngularFireModule.initializeApp no longer takes a default sign in method.
Sign in should be done with the Firebase SDK via firebase.auth.Auth:
login() {
this.afAuth.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
}
logout() {
this.afAuth.auth.signOut();
}
// Do not import from 'firebase' as you'd lose the tree shaking benefits
import * as firebase from 'firebase/app';
@NgModule({
declarations: [ App ],
exports: [ App ],
imports: [
AngularFireModule.initializeApp(environment.firebase, 'my-app'),
AngularFireDatabaseModule,
AngularFireAuthModule
],
bootstrap[ App ]
})
export class MyModule { }
@Component({
selector: 'my-app',
template: `
<div> {{ (items | async)? | json }} </div>
<div> {{ (user | async)? | json }} </div>
<button (click)="login()">Login</button>
<button (click)="logout()">Logout</button>
`
})
export class App {
user: Observable<firebase.User>;
items: FirebaseListObservable<any[]>;
constructor(afAuth: AngularFireAuth, db: AngularFireDatabase) {
this.user = afAuth.authState;
this.items = db.list('items');
}
login() {
this.afAuth.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
}
logout() {
this.afAuth.auth.signOut();
}
}
#API Reference
AngularFire Service
The recommended way to take advantage of the AngularFire library is to use the
injectable AngularFire service.
@Component({
template:`
<ul>
<li *ngFor="let question of questions | async">
{{question.text}}
</li>
</ul>
`
})
class App {
questions:Observable<Question[]>
constructor(af:AngularFire) {
// Get an observable of a synchronized array from <firebase-root>/questions
this.questions = af.database.list('/questions');
}
}
bootstrap(App, [
// Common injectable providers from the AngularFire lib
FIREBASE_PROVIDERS,
// Tell AngularFire the base URL for the Firebase used throughout
defaultFirebase('https://<some-firebase>.firebaseio.com')
]);
FIREBASE_PROVIDERS
Contains all AngularFire provider configuration for Angular's dependency injection.
Type: any[]
Usage:
bootstrap(App, FIREBASE_PROVIDERS);
defaultFirebase
Define the root url for the library, to resolve relative paths.
Type: string
Usage:
bootstrap(App, [
FIREBASE_PROVIDERS,
defaultFirebase('https://my.firebaseio.com')
]);
FirebaseRef
Injectable symbol to create a Firebase reference based on the url provided
by FirebaseUrl.
Type: Firebase
Usage:
FirebaseUrl
URL for the app's default Firebase database.
Type: string
Usage:
@Component({
selector: 'app',
template: `<a [href]="url">{{ url }}</a>`
})
class App {
constructor(@Inject(FirebaseUrl) public url: string) {}
}
bootstrap(App, [
FIREBASE_PROVIDERS,
defaultFirebase('https://my.firebaseio.com')
]);
AngularFireAuth
Type: class
Injectable service for managing authentication state. Extends rxjs ReplaySubject, which
represents an object that is both an observable sequence as well as an observer.
Logging In
To log in a user, call the login method on an instance of FirebaseAuth class. The method
has the following two signatures:
login(config?: AuthConfiguration): firebase.Promise<FirebaseAuthState>;
login(credentials?: EmailPasswordCredentials |
firebase.auth.AuthCredential | string): firebase.Promise<FirebaseAuthState>;
login(credentials: EmailPasswordCredentials |
firebase.auth.AuthCredential | string, config?: AuthConfiguration):
firebase.Promise<FirebaseAuthState>
The signature that is used depends on which AuthMethod you chose to use to login.
AuthMethods.Popup, AuthMethods.Redirect, and AuthMethods.Anonymous all use the
first signature whereas AuthMethods.CustomToken, AuthMethods.OAuthToken, and
AuthMethods.Password use the second signature. This is because if you use these three
AuthMethods you need to provide a credentials argument to login.
AuthConfiguration
You MUST provide an AuthConfiguration object to use the login method, however you
do not need to pass it to login correctly. Instead you may choose to pass the
configuration in through DI. This helps keep your components modular because they
can simply call login and it will use whichever options were provided through DI. You
can use the firebaseAuthConfigMethod to generate a Provider object which you can pass
to DI like so:
import {bootstrap} from '@angular/core';
import {
FIREBASE_PROVIDERS,
defaultFirebase,
firebaseAuthConfig,
AuthProviders,
AuthMethods
} from 'angularfire2';
bootstrap(MyApp, [
FIREBASE_PROVIDERS,
defaultFirebase('https://<some-firebase>.firebaseio.com'),
firebaseAuthConfig({
provider: AuthProviders.Facebook,
method: AuthMethods.Popup,
remember: 'default',
scope: ['email']
})
]);
Once you've done that you can simply call login on the auth object. This will
automatically use the options that were configured with DI. You can override those
options by providing an optional configuration object to the login method like so:
import {Component} from '@angular/core';
import {FirebaseAuth} from 'angularfire2';
@Component({
selector: 'my-component'
templateUrl: 'my_template.html'
})
export class MyApp {
constructor (private _auth: FirebaseAuth) {}
public doLogin () {
// This will perform popup auth with google oauth and the scope will be email
// Because those options were provided through bootstrap to DI, and we're
overriding the provider.
this._auth.login({
provider: AuthProviders.Google
});
}
}
The AuthConfiguration Object has the following signature
The AuthMethods and AuthProviders are enums, defining values for Methods and
Providers respectively.
See Facebook-Login and Google-Signin for more information.
Usage:
....
signInWithFacebook(): Promise<FirebaseAuthState> {
return this.auth$.login({
provider: AuthProviders.Facebook,
method: AuthMethods.Popup,
});
}
....
....
signInWithGoogle(): Promise<FirebaseAuthState> {
return this.auth$.login({
provider: AuthProviders.Google,
method: AuthMethods.Redirect,
});
....
login(credentials?: EmailPasswordCredentials | firebase.auth.AuthCredential |
string): firebase.Promise<FirebaseAuthState> :
Takes one of the three arguments as input. The EmailPasswordCredentials object is same,
as mentioned in createUser method. The login method can also take
a firebase.auth.AuthCredential object as mentioned here.
Usage:
....
signInWithEmail(): Promise<FirebaseAuthState> {
return this.auth$.login({
email: "yourName@gmail.com",
password: 'yourPassword'
});
....
signOut(): {
this.af.auth.logout().then(() => {
// user logged out
});
}
createUser(credentials: EmailPasswordCredentials):
firebase.Promise<FirebaseAuthState> : Creates a new user with email/password provided.
Returns a promise filled with FirebaseAuthState, which contains the uid of the created
user.
The credentials object is an object containing email and password of the user to be
created. See createUserWithEmailAndPassword for more information.
createNewUser(properties:Object): Promise<FirebaseAuthState> {
return this.auth.createUser({
email: 'uniqueName@gmail.com',
password: 'uniquePassword'
})
}
FirebaseListObservable
Subclass of rxjs Observable which also has methods for updating list-like Firebase data.
Type: class
Properties:
push:(val) => Promise: Add an element to the Firebase Database. This is the equivalent
of the Firebase SDK's
set() method. See Saving Data for info about restricted characters in object keys and
more details about saving data in the Database.
update:(item:Object) => void: Replace any child keys provided in val with the values
provided, but do not touch any other keys in the element. This is the equivalent of the
Firebase SDK's update() method.
remove:([item]) => void: Remove an element from the Firebase Database. If
no item argument is provided, it removes all elements from the list. This is the equivalent
of the Firebase SDK's remove() method.
FirebaseObjectObservable
Subclass of rxjs Observable which also has methods for syncing and updating object-like
Firebase data. {For collections and lists, see FirebaseListObservable.)
Type: class
Properties:
set:(val:any) => Promise:Replaces any data at this path in the Database with the value
provided here (or adds the data if it doesn't exist). This is the equivalent of the Firebase
SDK's
set() method. See Saving Data for info about restricted characters in object keys and
more details about saving data in the Database.
update:(val:Object) => void: Replace any child keys provided in val with the values
provided here. The primary difference between this method and set() above, is
that update() modifies only the keys provided, leaving any other data untouched,
where set() essentially replaces all data at the given path. This is the equivalent of the
Firebase SDK's update() method.
remove:() => void: Remove an element from the Firebase Database. If no item argument
is provided, it removes all elements from the list. This is the equivalent of the Firebase
SDK's remove() method.