If you’re using Firebase with Angular2 and TypeScript I suspect that you’ll probably need Firebase interactions as a form an of an Observable.
Here’s a snippet of a class called RxFirebase which gives you beautiful type-safe Observables from Firebase events.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import {Observable, Subscriber} from 'rxjs/Rx'

export enum EventType {
CHILD_ADDED, CHILD_REMOVED, CHILD_CHANGED, CHILD_MOVED, VALUE
}

export interface RxFirebaseResponse {
snapshot: FirebaseDataSnapshot
siblingKey: string
}

export class RxFirebasePayload implements RxFirebaseResponse {
snapshot: FirebaseDataSnapshot
siblingKey: string
constructor(snapshot: FirebaseDataSnapshot, siblingKey: string){
this.snapshot = snapshot;
this.siblingKey = siblingKey;
}
}

export class RxFirebase {

get ref(): Firebase {
return this.query.ref()
}

get uid(): string {
return this.ref.getAuth().uid
}

get authData(): FirebaseAuthData {
return this.ref.getAuth()
}

query: FirebaseQuery
constructor(query: FirebaseQuery){
this.query = query
}

child(path: string): RxFirebase {
return new RxFirebase(this.ref.child(path));
}

rx_observeAuth(): Observable<FirebaseAuthData> {
var self = this;
return new Observable((subscriber: Subscriber<FirebaseAuthData>) => {
var listener = (authData : FirebaseAuthData) => {
subscriber.next(authData);
}
self.ref.onAuth(listener);
return () => {
self.ref.offAuth(listener);
}
});
}

rx_remove(): Observable<{}> {
let self = this;
return new Observable((subscriber : Subscriber<{}>) => {
self.ref.remove((err) => {
if(err != null){
subscriber.error(err);
}else{
subscriber.next({});
subscriber.complete();
}
})
return () => {}
})
}

rx_update(data: any): Observable<{}> {
let self = this;
return new Observable((subscriber: Subscriber<{}>) => {
self.ref.update(data, (err) => {
if(err != null){
subscriber.error(err);
}else{
subscriber.next({});
subscriber.complete();
}
})
return () => {

}
});
}

rx_observe(eventType: EventType) : Observable<RxFirebaseResponse> {
var self = this;
return new Observable((subscriber : Subscriber<RxFirebaseResponse>) => {
var callback = (snapshot: FirebaseDataSnapshot, siblingKey: string) => {
subscriber.next(new RxFirebasePayload(snapshot, siblingKey))
}
self.query.on(self.convertToString(eventType), callback, err => {
subscriber.error(err);
})
return () => {
self.query.off(self.convertToString(eventType), callback);
}
});
}


orderByChild(key: string) : RxFirebase {
let newQuery = this.query.orderByChild(key);
return new RxFirebase(newQuery);
}

orderByValue(): RxFirebase {
let newQuery = this.query.orderByValue()
return new RxFirebase(newQuery);
}

orderByPriority(): RxFirebase {
let newQuery = this.query.orderByPriority();
return new RxFirebase(newQuery)
}

private convertToString(eventType: EventType) : string {
switch (eventType) {
case EventType.CHILD_ADDED:
return "child_added"
break;
case EventType.CHILD_CHANGED:
return "child_changed"
break
case EventType.CHILD_MOVED:
return "child_moved"
break
case EventType.CHILD_REMOVED:
return "child_removed"
break
case EventType.VALUE:
return "value"
break
default:
break;
}
}
}