@@ -15,7 +15,7 @@ @implementation FirestackDatabase
1515
1616RCT_EXPORT_MODULE (FirestackDatabase);
1717
18- RCT_EXPORT_METHOD (onDBEvent :(NSString *) path
18+ RCT_EXPORT_METHOD (on :(NSString *) path
1919 name:(NSString *) name
2020 callback:(RCTResponseSenderBlock) callback)
2121{
@@ -25,20 +25,38 @@ @implementation FirestackDatabase
2525
2626 FIRDatabaseReference *ref = [self getRefAtPath: path];
2727
28- [ref observeEventType: eventType
29- withBlock: ^(FIRDataSnapshot * _Nonnull snapshot) {
30- callback (@[[NSNull null ], [self snapshotToDict: snapshot]]);
31- }
32- withCancelBlock: ^(NSError * _Nonnull error) {
33- NSLog (@" Error onDBEvent: %@ " , [error debugDescription ]);
34- callback (@[@{
35- @" error" : @" onceError" ,
36- @" msg" : [error debugDescription ]
37- }]);
38- }];
28+ FIRDatabaseHandle handle = [ref observeEventType: eventType
29+ withBlock: ^(FIRDataSnapshot * _Nonnull snapshot) {
30+ NSDictionary *props =
31+ [self snapshotToDict: snapshot];
32+
33+ NSLog (@" props: %@ " , props);
34+ [self
35+ sendJSEvent: name
36+ props: @{
37+ @" eventName" : name,
38+ @" snapshot" : props
39+ }];
40+ }
41+ withCancelBlock: ^(NSError * _Nonnull error) {
42+ NSLog (@" Error onDBEvent: %@ " , [error debugDescription ]);
43+ [self
44+ sendJSEvent: DATABASE_ERROR_EVENT
45+ props: @{
46+ @" eventName" : DATABASE_ERROR_EVENT,
47+ @" msg" : [error debugDescription ]
48+ }];
49+ }];
50+
51+ int idx = [self storeDBHandle: handle];
52+
53+ callback (@[[NSNull null ], @{
54+ @" result" : @" success" ,
55+ @" handle" : @(idx)
56+ }]);
3957}
4058
41- RCT_EXPORT_METHOD (onDBEventOnce :(NSString *) path
59+ RCT_EXPORT_METHOD (onOnce :(NSString *) path
4260 name:(NSString *) name
4361 callback:(RCTResponseSenderBlock) callback)
4462{
@@ -58,6 +76,34 @@ @implementation FirestackDatabase
5876 }];
5977}
6078
79+ RCT_EXPORT_METHOD (off:(NSString *)path
80+ handleNumber:(NSInteger ) handleNumber
81+ callback:(RCTResponseSenderBlock) callback)
82+ {
83+ FIRDatabaseReference *ref = [self getRefAtPath: path];
84+
85+ if (handleNumber == -1 ) {
86+ [ref removeAllObservers ];
87+ } else {
88+ FIRDatabaseHandle handle = [[self storedDBHandles ] objectAtIndex: handleNumber];
89+ if (handle != nil ) {
90+ [ref removeObserverWithHandle: handle];
91+ [self removeDBHandle: handleNumber];
92+ } else {
93+ [ref removeAllObservers ];
94+ }
95+ }
96+ callback (@[[NSNull null ], @(true )]);
97+ }
98+
99+ RCT_EXPORT_METHOD (removeListeners:(NSString *) path
100+ callback:(RCTResponseSenderBlock) callback)
101+ {
102+ FIRDatabaseReference *ref = [self getRefAtPath: path];
103+ [ref removeAllObservers ];
104+ callback (@[[NSNull null ], @(true )]);
105+ }
106+
61107// Helpers
62108- (FIRDatabaseReference *) getRef
63109{
@@ -74,6 +120,38 @@ - (FIRDatabaseReference *) getRefAtPath:(NSString *) str
74120 return [rootRef child: str];
75121}
76122
123+ // Handles
124+ - (NSArray *) storedDBHandles
125+ {
126+ if (self._DBHandles == nil ) {
127+ self._DBHandles = [[NSMutableArray alloc ] init ];
128+ }
129+ return self._DBHandles ;
130+ }
131+
132+ - (int ) storeDBHandle : (FIRDatabaseHandle) handle
133+ {
134+ NSMutableArray *stored = [[self storedDBHandles ] mutableCopy ];
135+
136+ NSNumber *handleNum = [NSNumber numberWithUnsignedLong: handle];
137+
138+ [stored addObject: handleNum];
139+ self._DBHandles = stored;
140+
141+ int handleIdx = [stored indexOfObject: handleNum];
142+ return handleIdx;
143+ }
144+
145+ - (int ) removeDBHandle : (int ) idx
146+ {
147+ NSMutableArray *stored = [[self storedDBHandles ] mutableCopy ];
148+ if ([stored objectAtIndex: idx]) {
149+ [stored removeObjectAtIndex: idx];
150+ self._DBHandles = stored;
151+ }
152+ return idx;
153+ }
154+
77155- (NSDictionary *) snapshotToDict : (FIRDataSnapshot *) snapshot
78156{
79157 NSMutableDictionary *dict = [[NSMutableDictionary alloc ] init ];
@@ -93,32 +171,42 @@ - (int) eventTypeFromName:(NSString *)name
93171{
94172 int eventType = FIRDataEventTypeValue;
95173
96- if ([name isEqualToString: @" value " ]) {
174+ if ([name isEqualToString: DATABASE_VALUE_EVENT ]) {
97175 eventType = FIRDataEventTypeValue;
98- } else if ([name isEqualToString: @" child_added " ]) {
176+ } else if ([name isEqualToString: DATABASE_CHILD_ADDED_EVENT ]) {
99177 eventType = FIRDataEventTypeChildAdded;
100- } else if ([name isEqualToString: @" child_changed " ]) {
178+ } else if ([name isEqualToString: DATABASE_CHILD_MODIFIED_EVENT ]) {
101179 eventType = FIRDataEventTypeChildChanged;
102- } else if ([name isEqualToString: @" child_removed " ]) {
180+ } else if ([name isEqualToString: DATABASE_CHILD_REMOVED_EVENT ]) {
103181 eventType = FIRDataEventTypeChildRemoved;
104- } else if ([name isEqualToString: @" child_moved " ]) {
182+ } else if ([name isEqualToString: DATABASE_CHILD_MOVED_EVENT ]) {
105183 eventType = FIRDataEventTypeChildMoved;
106184 }
107185 return eventType;
108186}
109187
188+ // Not sure how to get away from this... yet
110189// Not sure how to get away from this... yet
111190- (NSArray <NSString *> *)supportedEvents {
112191 return @[
113- DATABASE_VALUE_EVENT
192+ DATABASE_VALUE_EVENT,
193+ DATABASE_CHILD_ADDED_EVENT,
194+ DATABASE_CHILD_MODIFIED_EVENT,
195+ DATABASE_CHILD_MOVED_EVENT,
196+ DATABASE_CHILD_REMOVED_EVENT
114197 ];
115198}
116199
117200- (void ) sendJSEvent : (NSString *)title
118201 props : (NSDictionary *)props
119202{
120- [self sendEventWithName: title
121- body: props];
203+ @try {
204+ [self sendEventWithName: title
205+ body: props];
206+ }
207+ @catch (NSException *err) {
208+ NSLog (@" An error occurred in sendJSEvent: %@ " , [err debugDescription ]);
209+ }
122210}
123211
124212@end
0 commit comments