https://slides.com/josefduran/angular2-angularfire2-angular-cli/
Remember dependencies: NodeJS 4 and up
$ npm install -g angular-cli
github repo: https://github.com/angular/angular-cli
$ ng new PROJECT_NAME
it will create the project folder and download initial dependencies needed
$ ng new simplechat
Project name: simplechat
$ npm install angularfire2 firebase@2.4.2 --save
There are a few steps for doing this...
This is based on the documentation on AngularFire2 repo and modified a little bit to fit our purposes.
Fixed to include proper version of Firebase
https://github.com/angular/angularfire2/
$ npm install typings -g
$ typings install --save --ambient firebase
this is so typescript can work with the Firebase lib
/* global require, module */
var Angular2App = require('angular-cli/lib/broccoli/angular2-app');
module.exports = function(defaults) {
return new Angular2App(defaults, {
vendorNpmFiles: [
'systemjs/dist/system-polyfills.js',
'systemjs/dist/system.src.js',
'zone.js/dist/*.js',
'es6-shim/es6-shim.js',
'reflect-metadata/*.js',
'rxjs/**/*.js',
'@angular/**/*.js',
// above are the existing entries
// below are the AngularFire entries
'angularfire2/**/*.+(js|js.map)',
'firebase/lib/*.+(js|js.map)'
]
});
};
in: angular-cli-build.js
$ ng build
Just to make sure we had everything ok
in: /dist/vendor folder we should have angularfire2 and firebase folders.
/** Map relative paths to URLs. */
const map: any = {
'firebase': 'vendor/firebase/lib/firebase-web.js',
'angularfire2': 'vendor/angularfire2'
};
/** User packages configuration. */
const packages: any = {
angularfire2: {
defaultExtension: 'js',
main: 'angularfire2.js'
}
};
in: /src/system-config.ts
Create an account and create a new database.
You will need to setup auth methods (we are going to use Github later) you can do it now or later. Remember to follow appropriate steps depending on the social login service you want to use.
import { bootstrap } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { SimplechatAppComponent, environment } from './app/';
import { FIREBASE_PROVIDERS, defaultFirebase } from 'angularfire2';
if (environment.production) {
enableProdMode();
}
bootstrap(SimplechatAppComponent, [
FIREBASE_PROVIDERS,
defaultFirebase('https://<your-firebase-app>.firebaseio.com')
]);
/src/main.ts, inject the Firebase providers, and specify your default Firebase
remember to replace <your-firebase-app> in the default Firebase url
$ ng generate route login
it will generate the component and inject the route data in the inmediate parent component
@Routes([
{path: '/login', component: LoginComponent}
])
in: /src/app/spdyjs.component.ts
@Routes([
{path: '/', component: LoginComponent}
])
Change path for root
Now the old injection problem in routes is solved, but we don't see the login component showing below our title.
There is a constructor instantiating the router missing from the code in our main component simplechat.component.ts
import { Component } from '@angular/core';
import { LoginComponent } from './+login';
import { Router, Routes, ROUTER_DIRECTIVES, ROUTER_PROVIDERS} from '@angular/router';
@Component({
moduleId: module.id,
selector: 'medjs-app',
templateUrl: 'medjs.component.html',
styleUrls: ['medjs.component.css'],
directives: [ROUTER_DIRECTIVES],
providers: [ROUTER_PROVIDERS]
})
@Routes([
{path: '/', component: LoginComponent}
])
export class MedjsAppComponent {
title = 'medjs works!';
// missing constructor here !!!
}
import { Component } from '@angular/core';
import { LoginComponent } from './+login';
import { Router, Routes, ROUTER_DIRECTIVES, ROUTER_PROVIDERS} from '@angular/router';
@Component({
moduleId: module.id,
selector: 'medjs-app',
templateUrl: 'medjs.component.html',
styleUrls: ['medjs.component.css'],
directives: [ROUTER_DIRECTIVES],
providers: [ROUTER_PROVIDERS]
})
@Routes([
{path: '/', component: LoginComponent}
])
export class MedjsAppComponent {
title = 'medjs works!';
constructor(private router: Router) { }
}
final result
import { bootstrap } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { SimplechatAppComponent, environment } from './app/';
import {FIREBASE_PROVIDERS,
defaultFirebase,
AngularFire,
AuthMethods,
AuthProviders,
firebaseAuthConfig} from 'angularfire2';
if (environment.production) {
enableProdMode();
}
bootstrap(SimplechatAppComponent, [
ROUTER_PROVIDERS,
FIREBASE_PROVIDERS,
defaultFirebase('https://<your-firebase-app>.firebaseio.com'),
firebaseAuthConfig({
provider: AuthProviders.Github,
method: AuthMethods.Popup
})
]);
in: /src/main.ts
import { AngularFire, AuthProviders, AuthMethods } from 'angularfire2';
Let's inject firebase auth on it
constructor(public af: AngularFire) {
this.af.auth.subscribe(auth => console.log(auth));
}
create a constructor to use it
<div *ngIf="af.auth">{{ (af.auth | async).auth.token.email }}</div>
<button (click)="login()">Login With Github</button>
and modify the HTML template adding:
In Angular 1.x we did some "ui-router" magic with an interceptor to prevent entering paths without proper auth... How we can so this here?
$ ng generate route chat
Let's create our second route
import { AngularFire, FirebaseListObservable, AuthProviders, AuthMethods } from 'angularfire2';
Let's inject the needed dependencies for it
constructor(private router: Router, public af: AngularFire) {
this.af.auth.subscribe(auth => {
// interceptor
if (auth) {
if (auth.uid) {
this.router.navigate(['/chat']);
}
} else {
this.router.navigate(['/']);
}
});
}
building some Firebase Auth observables to handle the routes permissions
import { Component } from '@angular/core';
import { Router, Routes, ROUTER_DIRECTIVES} from '@angular/router';
import { AngularFire, FirebaseListObservable, AuthProviders, AuthMethods } from 'angularfire2';
import { ChatComponent } from './+chat';
import { LoginComponent } from './+login';
@Component({
moduleId: module.id,
selector: 'simplechat-app',
templateUrl: 'simplechat.component.html',
styleUrls: ['simplechat.component.css'],
directives: [ROUTER_DIRECTIVES]
})
@Routes([
{path: '/', component: LoginComponent},
{path: '/chat', component: ChatComponent}
])
export class SimplechatAppComponent {
title = 'simplechat works!';
constructor(private router: Router, public af: AngularFire) {
this.af.auth.subscribe(auth => {
// interceptor
if (auth) {
if (auth.uid) {
this.router.navigate(['/chat']);
}
} else {
this.router.navigate(['/']);
}
});
}
logout() {
this.af.auth.logout();
}
}
final result in simplechat.component.ts
in our main component (simplechat.component.ts): piece of cake!
logout() {
this.af.auth.logout();
}
and call the method in the template (simplechat.component.html)
<h1>
{{title}}
</h1>
<a href="javascript:;" (click)="logout()" *ngIf="af.auth">logout</a>
<router-outlet></router-outlet>
We now have our main project and some auth with it. We can dive now in the chat app!
import { Component, OnInit } from '@angular/core';
import {AngularFire, FirebaseListObservable} from 'angularfire2';
@Component({
moduleId: module.id,
selector: 'app-chat',
templateUrl: 'chat.component.html',
styleUrls: ['chat.component.css']
})
export class ChatComponent implements OnInit {
messages: FirebaseListObservable<any[]>;
email:string;
constructor(public af: AngularFire) {
this.messages = af.database.list('/messages');
this.af.auth.subscribe(auth => {
this.email = auth.github.email;
});
}
add(newMsg: string) {
this.messages.push({
email: this.email,
text: newMsg
});
}
ngOnInit() {
}
}
a little magic from AngularFire2
<p>
chat works!
</p>
<form (ngSubmit)="add(newmsg.value)" #chatForm="ngForm">
<input type="text" #newmsg />
<button type="submit">send</button>
</form>
<ul *ngIf="messages">
<li *ngFor="let item of messages | async">
{{ item.email }}: {{ item.text }}
</li>
</ul>
chat.component.html
$ npm install -g firebase-tools
$ firebase login
$ firebase init
$ firebase deploy
We're going to use Firebase hosting for rapid deployment and testing, let's install it.
follow on console instructions on each step
https://github.com/josefduran/spdyjs
https://angular.io/docs/
https://github.com/angular/angularfire2
https://github.com/angular/angular-cli
https://firebase.google.com/docs/cli