Real-time features like notifications, fetching the details is a breeze with Firebase database and angular 2's async pipe. Firebase is pretty cool to store your data. It's ideal for blogs, notifications. If you are like me, you fan out the keys to various nodes(not store the entire denormalized structure). In that case, it's important to loop through all keys and get data at each element level. In this blog, we explore a technique to fetch the data using Angular 2's async pipe from Firebase database.
First, let's create an angular module for app initialization and then pipes for fetching the data.
Before starting install firebase package using npm.
First, let's create a module for initialization.
First, let's create an angular module for app initialization and then pipes for fetching the data.
Before starting install firebase package using npm.
npm install firebase --save
First, let's create a module for initialization.
firebase.module.ts :
//firebase.module.ts
import { NgModule } from "@angular/core";
import * as firebase from "firebase";
export interface IFirebaseConfig{
"apiKey": string,
"authDomain": string,
"databaseURL": string,
"storageBucket": string,
"messagingSenderId": string
}
@NgModule()
export class FirebaseConfigModule{
static init(config: IFirebaseConfig){
firebase.initializeApp(config);
return {
ngModule: FirebaseConfigModule
}
}
}
Now import the above module into application root module like this:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { FirebaseConfigModule } from './firebase.module';
@NgModule({
imports: [
BrowserModule,
FirebaseConfigModule.init(
{
"apiKey": "",
"authDomain": "",
"databaseURL": "",
"storageBucket": "",
"messagingSenderId": ""
}
)
],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Now you can use the firebase features anywhere in the application just by importing firebase from firebase package in the following manner.
...
@Component({
selector: "users",
template: `
User name: {{userName}}
`
})
export class UsersComponent {
public userName: string;
constructor(){
firebase.database().ref("users/-KiAAhNT6LZMHGS9c-4g/name").once("value", (data) => {
this.userName = data.val();
});
}
...
}
Cool, now everything works fine.
But how it would be if we had a pipe which accepts data location path and fetches data for us? instead of writing in the component each time when we want to fetch the data, It sounds great right? let's write a pipe to achieve this.
Add the following pipe function into firebase.module.ts:
@Pipe({name: "firePipeValue"})
export class FirebasePipe implements PipeTransform {
transform(ref: string, listenType: "on" | "once"="on"): Observable<any>{
return Observable.create((observer: Observer<any>) => {
function onValue(data){
observer.next(data.val());
}
if(listenType == "on"){
firebase.database().ref(ref).on("value", onValue);
}else{
firebase.database().ref(ref).once("value", onValue);
}
return function(){
firebase.database().ref(ref).off("value", onValue);
}
});
}
}
And change the FirebaseConfigModule class to the following manner.
@NgModule({
exports: [FirebasePipe],
declarations: [FirebasePipe]
})
export class FirebaseConfigModule{
static init(config: IFirebaseConfig){
firebase.initializeApp(config);
return {
ngModule: FirebaseConfigModule
}
}
}
Now you can use the pipe in the view like this:
{{'clients/-KiAAhNT6LZMHGS9c-4g/name' | firePipeValue:'on' | async}}
{{'clients/-Ki9saJqb03SACfx89_X' | firePipeValue:'off' | async}}
In this pipe we need to pass one argument "on" or "off". "on" is for listening to the data changes and if you don't want changes to reflect? pass the argument "off".
Note: Don't use this pipe for fetching lists of data. For fetching lists I have written another pipe, I will share that gist.
You can find the above code in the following gist URL:
https://gist.github.com/kurapatijayaram/e2f97d0966bf5baac07a5aa7a0c3e77d
No comments:
Post a Comment