@@ -2,7 +2,7 @@ import * as firebase from "../../firebase";
22import { AddEventListenerResult , FBData } from "../../firebase" ;
33import { 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