1717
1818#import < Firebase/Firebase.h>
1919#import < React/RCTUtils.h>
20+ #import < RNFBApp/RNFBRCTEventEmitter.h>
2021
2122#import " RNFBApp/RNFBSharedUtils.h"
2223#import " RNFBFunctionsModule.h"
23- #import < RNFBApp/RNFBRCTEventEmitter.h>
2424
2525@implementation RNFBFunctionsModule
2626#pragma mark -
@@ -117,8 +117,8 @@ @implementation RNFBFunctionsModule
117117 NSString *projectId = firebaseApp.options .projectID ?: @" " ;
118118 NSString *urlString;
119119 if (host != nil && port != nil ) {
120- urlString = [NSString stringWithFormat: @" http:// %@ : %@ / %@ / %@ / %@ " ,
121- host, port, projectId, customUrlOrRegion, name];
120+ urlString = [NSString
121+ stringWithFormat: @" http:// %@ : %@ / %@ / %@ / %@ " , host, port, projectId, customUrlOrRegion, name];
122122 } else {
123123 urlString = [NSString stringWithFormat: @" https://%@ -%@ .cloudfunctions.net/%@ " ,
124124 customUrlOrRegion, projectId, name];
@@ -150,60 +150,61 @@ @implementation RNFBFunctionsModule
150150 config.URLCache = nil ;
151151 NSURLSession *session = [NSURLSession sessionWithConfiguration: config];
152152
153- NSURLSessionDataTask *task =
154- [session dataTaskWithRequest: request
155- completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) {
156- if (error) {
157- NSMutableDictionary *body = [@{@" error" : error.localizedDescription ?: @" error" } mutableCopy];
158- [RNFBSharedUtils sendJSEventForApp: firebaseApp
159- name: RNFB_FUNCTIONS_STREAMING_EVENT
160- body: @{
161- @" listenerId" : listenerId,
162- @" eventName" : RNFB_FUNCTIONS_STREAMING_EVENT,
163- @" body" : body
164- }];
165- } else if ([response isKindOfClass: [NSHTTPURLResponse class ]] &&
166- [(NSHTTPURLResponse *)response statusCode ] >= 400 ) {
167- NSHTTPURLResponse *http = (NSHTTPURLResponse *)response;
168- NSString *msg = [NSString stringWithFormat: @" http_error_%ld _%@ " ,
169- (long )http.statusCode,
170- [NSHTTPURLResponse localizedStringForStatusCode: http.statusCode]];
171- NSMutableDictionary *body = [@{@" error" : msg} mutableCopy];
172- [RNFBSharedUtils sendJSEventForApp: firebaseApp
173- name: RNFB_FUNCTIONS_STREAMING_EVENT
174- body: @{
175- @" listenerId" : listenerId,
176- @" eventName" : RNFB_FUNCTIONS_STREAMING_EVENT,
177- @" body" : body
178- }];
179- } else if (data.length > 0 ) {
180- NSString *payload = [[NSString alloc ] initWithData: data encoding: NSUTF8StringEncoding];
181- // Split into lines (handles SSE or NDJSON)
182- [payload enumerateLinesUsingBlock: ^(NSString *line, BOOL *stop) {
183- if (line.length == 0 ) return ;
184- NSString *trimmed = [line hasPrefix: @" data: " ] ? [line substringFromIndex: 6 ] : line;
185- NSMutableDictionary *body = [@{@" text" : trimmed} mutableCopy];
186- [RNFBSharedUtils sendJSEventForApp: firebaseApp
187- name: RNFB_FUNCTIONS_STREAMING_EVENT
188- body: @{
189- @" listenerId" : listenerId,
190- @" eventName" : RNFB_FUNCTIONS_STREAMING_EVENT,
191- @" body" : body
192- }];
193- }];
194- }
195- // Always emit done at end
196- [RNFBSharedUtils sendJSEventForApp: firebaseApp
197- name: RNFB_FUNCTIONS_STREAMING_EVENT
198- body: @{
199- @" listenerId" : listenerId,
200- @" eventName" : RNFB_FUNCTIONS_STREAMING_EVENT,
201- @" body" : @{@" done" : @YES }
202- }];
203- @synchronized (httpsCallableStreamListeners) {
204- [httpsCallableStreamListeners removeObjectForKey: listenerId];
205- }
206- }];
153+ NSURLSessionDataTask *task = [session
154+ dataTaskWithRequest: request
155+ completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) {
156+ if (error) {
157+ NSMutableDictionary *body =
158+ [@{@" error" : error.localizedDescription ?: @" error" } mutableCopy];
159+ [RNFBSharedUtils sendJSEventForApp: firebaseApp
160+ name: RNFB_FUNCTIONS_STREAMING_EVENT
161+ body: @{
162+ @" listenerId" : listenerId,
163+ @" eventName" : RNFB_FUNCTIONS_STREAMING_EVENT,
164+ @" body" : body
165+ }];
166+ } else if ([response isKindOfClass: [NSHTTPURLResponse class ]] &&
167+ [(NSHTTPURLResponse *)response statusCode ] >= 400 ) {
168+ NSHTTPURLResponse *http = (NSHTTPURLResponse *)response;
169+ NSString *msg = [NSString
170+ stringWithFormat: @" http_error_%ld _%@ " , (long )http.statusCode,
171+ [NSHTTPURLResponse localizedStringForStatusCode: http.statusCode]];
172+ NSMutableDictionary *body = [@{@" error" : msg} mutableCopy];
173+ [RNFBSharedUtils sendJSEventForApp: firebaseApp
174+ name: RNFB_FUNCTIONS_STREAMING_EVENT
175+ body: @{
176+ @" listenerId" : listenerId,
177+ @" eventName" : RNFB_FUNCTIONS_STREAMING_EVENT,
178+ @" body" : body
179+ }];
180+ } else if (data.length > 0 ) {
181+ NSString *payload = [[NSString alloc ] initWithData: data encoding: NSUTF8StringEncoding];
182+ // Split into lines (handles SSE or NDJSON)
183+ [payload enumerateLinesUsingBlock: ^(NSString *line, BOOL *stop) {
184+ if (line.length == 0 ) return ;
185+ NSString *trimmed = [line hasPrefix: @" data: " ] ? [line substringFromIndex: 6 ] : line;
186+ NSMutableDictionary *body = [@{@" text" : trimmed} mutableCopy];
187+ [RNFBSharedUtils sendJSEventForApp: firebaseApp
188+ name: RNFB_FUNCTIONS_STREAMING_EVENT
189+ body: @{
190+ @" listenerId" : listenerId,
191+ @" eventName" : RNFB_FUNCTIONS_STREAMING_EVENT,
192+ @" body" : body
193+ }];
194+ }];
195+ }
196+ // Always emit done at end
197+ [RNFBSharedUtils sendJSEventForApp: firebaseApp
198+ name: RNFB_FUNCTIONS_STREAMING_EVENT
199+ body: @{
200+ @" listenerId" : listenerId,
201+ @" eventName" : RNFB_FUNCTIONS_STREAMING_EVENT,
202+ @" body" : @{@" done" : @YES }
203+ }];
204+ @synchronized (httpsCallableStreamListeners) {
205+ [httpsCallableStreamListeners removeObjectForKey: listenerId];
206+ }
207+ }];
207208
208209 @synchronized (httpsCallableStreamListeners) {
209210 httpsCallableStreamListeners[listenerId] = task;
@@ -229,7 +230,7 @@ @implementation RNFBFunctionsModule
229230 if (!httpsCallableStreamListeners) {
230231 httpsCallableStreamListeners = [NSMutableDictionary dictionary ];
231232 }
232-
233+
233234 // Use the provided URL directly
234235 NSURLComponents *components = [NSURLComponents componentsWithString: url];
235236 if (components == nil ) {
@@ -243,14 +244,14 @@ @implementation RNFBFunctionsModule
243244 }];
244245 return ;
245246 }
246-
247+
247248 // Override to emulator if provided
248249 if (host != nil && port != nil ) {
249250 components.scheme = @" http" ;
250251 components.host = host;
251252 components.port = port;
252253 }
253-
254+
254255 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: [components URL ]];
255256 [request setHTTPMethod: @" GET" ];
256257 [request setValue: @" text/event-stream, application/x-ndjson, */*" forHTTPHeaderField: @" Accept" ];
@@ -260,60 +261,61 @@ @implementation RNFBFunctionsModule
260261 config.URLCache = nil ;
261262 NSURLSession *session = [NSURLSession sessionWithConfiguration: config];
262263
263- NSURLSessionDataTask *task =
264- [session dataTaskWithRequest: request
265- completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) {
266- if (error) {
267- NSMutableDictionary *body = [@{@" error" : error.localizedDescription ?: @" error" } mutableCopy];
268- [RNFBSharedUtils sendJSEventForApp: firebaseApp
269- name: RNFB_FUNCTIONS_STREAMING_EVENT
270- body: @{
271- @" listenerId" : listenerId,
272- @" eventName" : RNFB_FUNCTIONS_STREAMING_EVENT,
273- @" body" : body
274- }];
275- } else if ([response isKindOfClass: [NSHTTPURLResponse class ]] &&
276- [(NSHTTPURLResponse *)response statusCode ] >= 400 ) {
277- NSHTTPURLResponse *http = (NSHTTPURLResponse *)response;
278- NSString *msg = [NSString stringWithFormat: @" http_error_%ld _%@ " ,
279- (long )http.statusCode,
280- [NSHTTPURLResponse localizedStringForStatusCode: http.statusCode]];
281- NSMutableDictionary *body = [@{@" error" : msg} mutableCopy];
282- [RNFBSharedUtils sendJSEventForApp: firebaseApp
283- name: RNFB_FUNCTIONS_STREAMING_EVENT
284- body: @{
285- @" listenerId" : listenerId,
286- @" eventName" : RNFB_FUNCTIONS_STREAMING_EVENT,
287- @" body" : body
288- }];
289- } else if (data.length > 0 ) {
290- NSString *payload = [[NSString alloc ] initWithData: data encoding: NSUTF8StringEncoding];
291- // Split into lines (handles SSE or NDJSON)
292- [payload enumerateLinesUsingBlock: ^(NSString *line, BOOL *stop) {
293- if (line.length == 0 ) return ;
294- NSString *trimmed = [line hasPrefix: @" data: " ] ? [line substringFromIndex: 6 ] : line;
295- NSMutableDictionary *body = [@{@" text" : trimmed} mutableCopy];
296- [RNFBSharedUtils sendJSEventForApp: firebaseApp
297- name: RNFB_FUNCTIONS_STREAMING_EVENT
298- body: @{
299- @" listenerId" : listenerId,
300- @" eventName" : RNFB_FUNCTIONS_STREAMING_EVENT,
301- @" body" : body
302- }];
303- }];
304- }
305- // Always emit done at end
306- [RNFBSharedUtils sendJSEventForApp: firebaseApp
307- name: RNFB_FUNCTIONS_STREAMING_EVENT
308- body: @{
309- @" listenerId" : listenerId,
310- @" eventName" : RNFB_FUNCTIONS_STREAMING_EVENT,
311- @" body" : @{@" done" : @YES }
312- }];
313- @synchronized (httpsCallableStreamListeners) {
314- [httpsCallableStreamListeners removeObjectForKey: listenerId];
315- }
316- }];
264+ NSURLSessionDataTask *task = [session
265+ dataTaskWithRequest: request
266+ completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) {
267+ if (error) {
268+ NSMutableDictionary *body =
269+ [@{@" error" : error.localizedDescription ?: @" error" } mutableCopy];
270+ [RNFBSharedUtils sendJSEventForApp: firebaseApp
271+ name: RNFB_FUNCTIONS_STREAMING_EVENT
272+ body: @{
273+ @" listenerId" : listenerId,
274+ @" eventName" : RNFB_FUNCTIONS_STREAMING_EVENT,
275+ @" body" : body
276+ }];
277+ } else if ([response isKindOfClass: [NSHTTPURLResponse class ]] &&
278+ [(NSHTTPURLResponse *)response statusCode ] >= 400 ) {
279+ NSHTTPURLResponse *http = (NSHTTPURLResponse *)response;
280+ NSString *msg = [NSString
281+ stringWithFormat: @" http_error_%ld _%@ " , (long )http.statusCode,
282+ [NSHTTPURLResponse localizedStringForStatusCode: http.statusCode]];
283+ NSMutableDictionary *body = [@{@" error" : msg} mutableCopy];
284+ [RNFBSharedUtils sendJSEventForApp: firebaseApp
285+ name: RNFB_FUNCTIONS_STREAMING_EVENT
286+ body: @{
287+ @" listenerId" : listenerId,
288+ @" eventName" : RNFB_FUNCTIONS_STREAMING_EVENT,
289+ @" body" : body
290+ }];
291+ } else if (data.length > 0 ) {
292+ NSString *payload = [[NSString alloc ] initWithData: data encoding: NSUTF8StringEncoding];
293+ // Split into lines (handles SSE or NDJSON)
294+ [payload enumerateLinesUsingBlock: ^(NSString *line, BOOL *stop) {
295+ if (line.length == 0 ) return ;
296+ NSString *trimmed = [line hasPrefix: @" data: " ] ? [line substringFromIndex: 6 ] : line;
297+ NSMutableDictionary *body = [@{@" text" : trimmed} mutableCopy];
298+ [RNFBSharedUtils sendJSEventForApp: firebaseApp
299+ name: RNFB_FUNCTIONS_STREAMING_EVENT
300+ body: @{
301+ @" listenerId" : listenerId,
302+ @" eventName" : RNFB_FUNCTIONS_STREAMING_EVENT,
303+ @" body" : body
304+ }];
305+ }];
306+ }
307+ // Always emit done at end
308+ [RNFBSharedUtils sendJSEventForApp: firebaseApp
309+ name: RNFB_FUNCTIONS_STREAMING_EVENT
310+ body: @{
311+ @" listenerId" : listenerId,
312+ @" eventName" : RNFB_FUNCTIONS_STREAMING_EVENT,
313+ @" body" : @{@" done" : @YES }
314+ }];
315+ @synchronized (httpsCallableStreamListeners) {
316+ [httpsCallableStreamListeners removeObjectForKey: listenerId];
317+ }
318+ }];
317319
318320 @synchronized (httpsCallableStreamListeners) {
319321 httpsCallableStreamListeners[listenerId] = task;
0 commit comments