Skip to content
This repository was archived by the owner on Apr 4, 2023. It is now read-only.

Commit b08f534

Browse files
committed
[query] - Rework database/index Query class to use the new query api
1 parent e8406dc commit b08f534

File tree

1 file changed

+63
-116
lines changed

1 file changed

+63
-116
lines changed

src/app/database/index.ts

Lines changed: 63 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as firebase from "../../firebase";
22
import { AddEventListenerResult, FBData } from "../../firebase";
33
import { nextPushId } from "./util/NextPushId";
44

5-
export module database {
5+
export namespace database {
66
export interface DataSnapshot {
77
// child(path: string): DataSnapshot;
88
exists(): boolean;
@@ -19,137 +19,85 @@ export module database {
1919
}
2020

2121
export class Query {
22-
private static registeredListeners: Map<string, Array<any>> = new Map();
23-
private static registeredCallbacks: Map<string, Array<(a: DataSnapshot | null, b?: string) => any>> = new Map();
24-
2522
protected path: string;
26-
23+
private queryObject: firebase.Query;
2724
constructor(path: string) {
2825
this.path = path;
26+
this.queryObject = firebase.webQuery(this.path);
2927
}
3028

31-
public on(eventType /* TODO use */: string, callback: (a: DataSnapshot | null, b?: string) => any, cancelCallbackOrContext?: Object | null, context?: Object | null): (a: DataSnapshot | null, b?: string) => any {
32-
const onValueEvent = result => {
33-
if (result.error) {
34-
callback(result);
35-
} else {
36-
callback({
37-
key: result.key,
38-
val: () => result.value,
39-
exists: () => !!result.value
40-
});
41-
}
42-
};
43-
44-
firebase.addValueEventListener(onValueEvent, this.path).then(
45-
(result: AddEventListenerResult) => {
46-
if (!Query.registeredListeners.has(this.path)) {
47-
Query.registeredListeners.set(this.path, []);
48-
}
49-
Query.registeredListeners.set(this.path, Query.registeredListeners.get(this.path).concat(result.listeners));
50-
},
51-
error => {
52-
console.log("firebase.database().on error: " + error);
53-
}
54-
);
55-
56-
// remember the callbacks as we may need them for 'query' events
57-
if (!Query.registeredCallbacks.has(this.path)) {
58-
Query.registeredCallbacks.set(this.path, []);
59-
}
60-
Query.registeredCallbacks.get(this.path).push(callback);
61-
62-
return null;
29+
/**
30+
* Listens for data changes at a particular location
31+
* @param eventType One of the following strings: "value", "child_added", "child_changed", "child_removed", or "child_moved."
32+
* @param callback A callback that fires when the specified event occurs. The callback will be passed a DataSnapshot.
33+
* @returns The provided callback function is returned unmodified.
34+
*/
35+
public on(eventType: string, callback: (a: DataSnapshot | null, b?: string) => any,
36+
cancelCallbackOrContext?: Object | null, context?: Object | null): (a: DataSnapshot | null, b?: string) => Function {
37+
38+
/**
39+
* Follow webApi which uses the eventType. Works right now but running into issue because we don't
40+
* pass back a DataSnapshot with forEach / getChildren() implemented. So when an event fires the user
41+
* gets the updated values, but it's not sorted. In Android and Web you would loop through the children
42+
* (getChildren() and forEach()) which would be returned in the query order.
43+
* See: https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#forEach
44+
*/
45+
this.queryObject.on(eventType, callback).catch( error => {
46+
console.log("firebase.database().on error: " + error);
47+
});
48+
return callback; // According to firebase doc we just return the callback given
6349
}
6450

65-
public off(eventType? /* TODO use */: string, callback?: (a: DataSnapshot, b?: string | null) => any, context?: Object | null): any {
66-
if (Query.registeredListeners.has(this.path)) {
67-
firebase.removeEventListeners(Query.registeredListeners.get(this.path), this.path).then(
68-
result => Query.registeredListeners.delete(this.path),
69-
error => console.log("firebase.database().off error: " + error)
70-
);
71-
}
72-
Query.registeredCallbacks.delete(this.path);
73-
return null;
51+
/**
52+
* Remove all callbacks for given eventType. If not eventType is given this
53+
* detaches all callbacks previously attached with on().
54+
*/
55+
public off(eventType?: string, callback?: (a: DataSnapshot, b?: string | null) => any, context?: Object | null): void {
56+
// TODO: use callback rather than remove ALL listeners for a given eventType
57+
this.queryObject.off(eventType);
7458
}
7559

76-
public once(eventType: string, successCallback?: (a: DataSnapshot, b?: string) => any, failureCallbackOrContext?: Object | null, context?: Object | null): Promise<DataSnapshot> {
77-
return new Promise((resolve, reject) => {
78-
firebase.getValue(this.path).then(result => {
79-
resolve({
80-
key: result.key,
81-
val: () => result.value,
82-
exists: () => !!result.value
83-
});
84-
});
85-
});
60+
/**
61+
* Listens for exactly one event of the specified event type, and then stops listening.
62+
* @param eventType One of the following strings: "value", "child_added", "child_changed", "child_removed", or "child_moved."
63+
*/
64+
public once(eventType: string, successCallback?: (a: DataSnapshot, b?: string) => any,
65+
failureCallbackOrContext?: Object | null, context?: Object | null): Promise<DataSnapshot> {
66+
return this.queryObject.once(eventType);
8667
}
8768

88-
private getOnValueEventHandler(): (data: FBData) => void {
89-
return result => {
90-
const callbacks = Query.registeredCallbacks.get(this.path);
91-
callbacks && callbacks.map(callback => {
92-
callback({
93-
key: result.key,
94-
val: () => result.value,
95-
exists: () => !!result.value
96-
});
97-
});
98-
};
69+
/**
70+
* Generates a new Query object ordered by the specified child key. Queries can only order
71+
* by one key at a time. Calling orderByChild() multiple times on the same query is an error.
72+
* @param child child key to order the results by
73+
*/
74+
public orderByChild(child: string): firebase.Query {
75+
return this.queryObject.orderByChild(child);
9976
}
100-
101-
public orderByChild(child: string): Query {
102-
firebase.query(
103-
this.getOnValueEventHandler(),
104-
this.path,
105-
{
106-
orderBy: {
107-
type: firebase.QueryOrderByType.CHILD,
108-
value: child
109-
}
110-
}
111-
);
112-
return this;
77+
/**
78+
* Generates a new Query object ordered by key.
79+
* Sorts the results of a query by their (ascending) key values.
80+
*/
81+
public orderByKey(): firebase.Query {
82+
return this.queryObject.orderByKey();
11383
}
11484

115-
public orderByKey(): Query {
116-
firebase.query(
117-
this.getOnValueEventHandler(),
118-
this.path,
119-
{
120-
orderBy: {
121-
type: firebase.QueryOrderByType.KEY
122-
}
123-
}
124-
);
125-
return this;
85+
/**
86+
* Generates a new Query object ordered by priority
87+
*/
88+
public orderByPriority(): firebase.Query {
89+
return this.queryObject.orderByPriority();
12690
}
12791

128-
public orderByPriority(): Query {
129-
firebase.query(
130-
this.getOnValueEventHandler(),
131-
this.path,
132-
{
133-
orderBy: {
134-
type: firebase.QueryOrderByType.PRIORITY
135-
}
136-
}
137-
);
138-
return this;
92+
/**
93+
* Generates a new Query object ordered by value.If the children of a query are all scalar values
94+
* (string, number, or boolean), you can order the results by their (ascending) values.
95+
*/
96+
public orderByValue(): firebase.Query {
97+
return this.queryObject.orderByValue();
13998
}
14099

141-
public orderByValue(): Query {
142-
firebase.query(
143-
this.getOnValueEventHandler(),
144-
this.path,
145-
{
146-
orderBy: {
147-
type: firebase.QueryOrderByType.VALUE
148-
}
149-
}
150-
);
151-
return this;
152-
}
100+
// Didn't expose the filterby functions because they should be run after an orderby. (TODO: Limitby are exceptions....)
153101
}
154102

155103
export class Reference extends Query {
@@ -258,8 +206,7 @@ export module database {
258206
}
259207
}
260208

261-
export interface ThenableReference extends Reference /*, PromiseLike<any> */
262-
{
209+
export interface ThenableReference extends Reference /*, PromiseLike<any> */ {
263210
}
264211

265212
export class Database {

0 commit comments

Comments
 (0)