Auto complete early when no user listeners.
This is to clear up memory on the objective-c side without needing to signal the start/stop of user listeners.
This commit is contained in:
parent
a8b4435abf
commit
6a69ae66b1
|
@ -17,7 +17,6 @@
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation RNFirebaseNotifications {
|
@implementation RNFirebaseNotifications {
|
||||||
BOOL isUserHandlingOnNotificationDisplayed;
|
|
||||||
NSMutableDictionary<NSString *, void (^)(UIBackgroundFetchResult)> *completionHandlers;
|
NSMutableDictionary<NSString *, void (^)(UIBackgroundFetchResult)> *completionHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +56,7 @@ RCT_EXPORT_MODULE();
|
||||||
|
|
||||||
// Set static instance for use from AppDelegate
|
// Set static instance for use from AppDelegate
|
||||||
theRNFirebaseNotifications = self;
|
theRNFirebaseNotifications = self;
|
||||||
|
completionHandlers = [[NSMutableDictionary alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
// PRE-BRIDGE-EVENTS: Consider enabling this to allow events built up before the bridge is built to be sent to the JS side
|
// PRE-BRIDGE-EVENTS: Consider enabling this to allow events built up before the bridge is built to be sent to the JS side
|
||||||
|
@ -98,31 +98,6 @@ RCT_EXPORT_MODULE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(startHandlingNotificationDisplayed) {
|
|
||||||
if(isUserHandlingOnNotificationDisplayed == YES) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
isUserHandlingOnNotificationDisplayed = YES;
|
|
||||||
|
|
||||||
completionHandlers = [[NSMutableDictionary alloc] init];
|
|
||||||
}
|
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(stopHandlingNotificationDisplayed) {
|
|
||||||
if(isUserHandlingOnNotificationDisplayed == NO) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
isUserHandlingOnNotificationDisplayed = NO;
|
|
||||||
|
|
||||||
NSArray *allHandlers = completionHandlers.allValues;
|
|
||||||
for (void (^ completionHandler)(UIBackgroundFetchResult) in allHandlers) {
|
|
||||||
completionHandler(UIBackgroundFetchResultNoData);
|
|
||||||
}
|
|
||||||
[completionHandlers removeAllObjects];
|
|
||||||
completionHandlers = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(complete:(NSString*)handlerKey fetchResult:(UIBackgroundFetchResult)fetchResult) {
|
RCT_EXPORT_METHOD(complete:(NSString*)handlerKey fetchResult:(UIBackgroundFetchResult)fetchResult) {
|
||||||
void (^completionHandler)(UIBackgroundFetchResult) = completionHandlers[handlerKey];
|
void (^completionHandler)(UIBackgroundFetchResult) = completionHandlers[handlerKey];
|
||||||
completionHandlers[handlerKey] = nil;
|
completionHandlers[handlerKey] = nil;
|
||||||
|
@ -132,15 +107,6 @@ RCT_EXPORT_METHOD(complete:(NSString*)handlerKey fetchResult:(UIBackgroundFetchR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)executeOrStoreCompletionHandler:(void (^ _Nonnull)(UIBackgroundFetchResult))completionHandler notification:(NSDictionary *)notification {
|
|
||||||
if(isUserHandlingOnNotificationDisplayed) {
|
|
||||||
NSString *handlerKey = notification[@"notificationId"];
|
|
||||||
completionHandlers[handlerKey] = completionHandler;
|
|
||||||
} else {
|
|
||||||
completionHandler(UIBackgroundFetchResultNoData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen for background messages
|
// Listen for background messages
|
||||||
- (void)didReceiveRemoteNotification:(NSDictionary *)userInfo
|
- (void)didReceiveRemoteNotification:(NSDictionary *)userInfo
|
||||||
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
|
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
|
||||||
|
@ -153,6 +119,7 @@ RCT_EXPORT_METHOD(complete:(NSString*)handlerKey fetchResult:(UIBackgroundFetchR
|
||||||
}
|
}
|
||||||
|
|
||||||
NSDictionary *notification = [self parseUserInfo:userInfo];
|
NSDictionary *notification = [self parseUserInfo:userInfo];
|
||||||
|
NSString *handlerKey = notification[@"notificationId"];
|
||||||
|
|
||||||
NSString *event;
|
NSString *event;
|
||||||
if (RCTSharedApplication().applicationState == UIApplicationStateBackground) {
|
if (RCTSharedApplication().applicationState == UIApplicationStateBackground) {
|
||||||
|
@ -180,8 +147,8 @@ RCT_EXPORT_METHOD(complete:(NSString*)handlerKey fetchResult:(UIBackgroundFetchR
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[self executeOrStoreCompletionHandler:completionHandler notification:notification];
|
completionHandlers[handlerKey] = completionHandler;
|
||||||
|
|
||||||
[self sendJSEvent:self name:event body:notification];
|
[self sendJSEvent:self name:event body:notification];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,11 +128,14 @@ export default class Notifications extends ModuleBase {
|
||||||
android: () => {},
|
android: () => {},
|
||||||
});
|
});
|
||||||
|
|
||||||
SharedEventEmitter.emit(
|
const publicEventName = 'onNotificationDisplayed';
|
||||||
'onNotificationDisplayed',
|
|
||||||
rnNotification,
|
if (!hasListeners(publicEventName)) {
|
||||||
done
|
// if user is not handling completion then we need to
|
||||||
);
|
done(this.backgroundFetchResult.noData);
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedEventEmitter.emit(publicEventName, rnNotification, done);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -271,10 +274,12 @@ export default class Notifications extends ModuleBase {
|
||||||
nextOrObserver: OnNotification | OnNotificationObserver
|
nextOrObserver: OnNotification | OnNotificationObserver
|
||||||
): () => any {
|
): () => any {
|
||||||
const isNext = isFunction(nextOrObserver);
|
const isNext = isFunction(nextOrObserver);
|
||||||
const isObserver = isObject(nextOrObserver) && isFunction(nextOrObserver.next);
|
const isObserver =
|
||||||
if (!isNext && !isObserver) {
|
isObject(nextOrObserver) && isFunction(nextOrObserver.next);
|
||||||
|
const eventName = 'onNotificationDisplayed';
|
||||||
|
if (!isNext && !isObserver) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Notifications.onNotificationDisplayed failed: First argument must be a function or observer object with a `next` function.'
|
`Notifications.${eventName} failed: First argument must be a function or observer object with a \`next\` function.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,24 +290,21 @@ export default class Notifications extends ModuleBase {
|
||||||
listener = nextOrObserver;
|
listener = nextOrObserver;
|
||||||
}
|
}
|
||||||
|
|
||||||
const autoCompletingListener: OnNotification = async (notification, done) => {
|
const autoCompletingListener: OnNotification = async (
|
||||||
|
notification,
|
||||||
|
done
|
||||||
|
) => {
|
||||||
const listenerResult = await listener(notification, done);
|
const listenerResult = await listener(notification, done);
|
||||||
done(this.backgroundFetchResult.noData);
|
done(this.backgroundFetchResult.noData);
|
||||||
return listenerResult;
|
return listenerResult;
|
||||||
};
|
};
|
||||||
|
|
||||||
getLogger(this).info('Creating onNotificationDisplayed listener');
|
getLogger(this).info(`Creating ${eventName} listener`);
|
||||||
SharedEventEmitter.addListener('onNotificationDisplayed', autoCompletingListener);
|
SharedEventEmitter.addListener(eventName, autoCompletingListener);
|
||||||
if (hasListeners('onNotificationDisplayed')) {
|
|
||||||
getNativeModule(this).startHandlingNotificationDisplayed();
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
getLogger(this).info('Removing onNotificationDisplayed listener');
|
getLogger(this).info(`Removing ${eventName} listener`);
|
||||||
SharedEventEmitter.removeListener('onNotificationDisplayed', autoCompletingListener);
|
SharedEventEmitter.removeListener(eventName, autoCompletingListener);
|
||||||
if (!hasListeners('onNotificationDisplayed')) {
|
|
||||||
getNativeModule(this).stopHandlingNotificationDisplayed();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue