Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/mediamonks/master'
Browse files Browse the repository at this point in the history
Merges and resolves #797
  • Loading branch information
dpa99c committed May 22, 2023
2 parents abd4825 + 768750f commit b47eb31
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 36 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,9 @@ See [Specifying Android library versions](#specifying-android-library-versions)
- `--variable IOS_ENABLE_CRITICAL_ALERTS_ENABLED=true`
- See [iOS critical notifications](#ios-critical-notifications)
- Ensure the associated app provisioning profile also has this capability enabled.
- `IOS_FCM_ENABLED` - allows to completely disable push notifications functionality of the plugin (not just the automatic initialization that is covered by `FIREBASE_FCM_AUTOINIT_ENABLED` variable).
- Defaults to `true`, if not specified; i.e. FCM is enabled by default.
- This can be handy if you are using this plugin for e.g. Crashlytics and handle push notifications using another plugin. Use `--variable IOS_FCM_ENABLED=false` in this case.

## Supported Cordova Versions
- cordova: `>= 10`
Expand Down
1 change: 1 addition & 0 deletions plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
<hook type="before_plugin_uninstall" src="scripts/ios/before_plugin_uninstall.js" />

<preference name="IOS_USE_PRECOMPILED_FIRESTORE_POD" default="false" />
<preference name="IOS_FCM_ENABLED" default="true" />

<js-module name="FirebasePlugin" src="www/firebase.js">
<clobbers target="FirebasePlugin" />
Expand Down
10 changes: 10 additions & 0 deletions scripts/ios/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,16 @@ end
appPlistModified = true;
}

if(pluginVariables['IOS_FCM_ENABLED'] === 'false'){
// Use GoogleService-Info.plist to pass this to the native part reducing noise in Info.plist.
// A prefix should make it more clear that this is not the variable of the SDK.
googlePlist["FIREBASEX_IOS_FCM_ENABLED"] = false;
googlePlistModified = true;
// FCM auto-init must be disabled early via the Info.plist in this case.
appPlist["FirebaseMessagingAutoInitEnabled"] = false;
appPlistModified = true;
}

if(googlePlistModified) fs.writeFileSync(path.resolve(iosPlatform.dest), plist.build(googlePlist));
if(appPlistModified) fs.writeFileSync(path.resolve(iosPlatform.appPlist), plist.build(appPlist));
if(entitlementsPlistsModified){
Expand Down
64 changes: 42 additions & 22 deletions src/ios/AppDelegate+FirebasePlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ @interface AppDelegate () <UNUserNotificationCenterDelegate, FIRMessagingDelegat
@implementation AppDelegate (FirebasePlugin)

static AppDelegate* instance;
static id <UNUserNotificationCenterDelegate> _previousDelegate;

+ (AppDelegate*) instance {
return instance;
Expand All @@ -26,6 +25,7 @@ + (AppDelegate*) instance {
static NSDictionary* mutableUserInfo;
static FIRAuthStateDidChangeListenerHandle authStateChangeListener;
static bool authStateChangeListenerInitialized = false;
static __weak id <UNUserNotificationCenterDelegate> _prevUserNotificationCenterDelegate = nil;

+ (void)load {
Method original = class_getInstanceMethod(self, @selector(application:didFinishLaunchingWithOptions:));
Expand Down Expand Up @@ -72,20 +72,23 @@ - (BOOL)application:(UIApplication *)application swizzledDidFinishLaunchingWithO
// Assume that another call (probably from another plugin) did so with the plist
isFirebaseInitializedWithPlist = true;
}

// Set UNUserNotificationCenter delegate
if ([UNUserNotificationCenter currentNotificationCenter].delegate != nil) {
_previousDelegate = [UNUserNotificationCenter currentNotificationCenter].delegate;
}
[UNUserNotificationCenter currentNotificationCenter].delegate = self;

// Set FCM messaging delegate
[FIRMessaging messaging].delegate = self;

if (self.isFCMEnabled) {
// Setting the delegate even if FCM is disabled would cause conflicts with other plugins dealing
// with push notifications (e.g. `urbanairship-cordova`).
_prevUserNotificationCenterDelegate = [UNUserNotificationCenter currentNotificationCenter].delegate;
[UNUserNotificationCenter currentNotificationCenter].delegate = self;

// Set FCM messaging delegate
[FIRMessaging messaging].delegate = self;
} else {
// This property is persistent thus ensuring it stays in sync with FCM settings in newer versions of the app.
[[FIRMessaging messaging] setAutoInitEnabled:NO];
}

// Setup Firestore
[FirebasePlugin setFirestore:[FIRFirestore firestore]];


authStateChangeListener = [[FIRAuth auth] addAuthStateDidChangeListener:^(FIRAuth * _Nonnull auth, FIRUser * _Nullable user) {
@try {
if(!authStateChangeListenerInitialized){
Expand All @@ -98,7 +101,6 @@ - (BOOL)application:(UIApplication *)application swizzledDidFinishLaunchingWithO
}
}];


self.applicationInBackground = @(YES);

}@catch (NSException *exception) {
Expand All @@ -108,6 +110,10 @@ - (BOOL)application:(UIApplication *)application swizzledDidFinishLaunchingWithO
return YES;
}

- (BOOL)isFCMEnabled {
return FirebasePlugin.firebasePlugin.isFCMEnabled;
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
self.applicationInBackground = @(NO);
@try {
Expand Down Expand Up @@ -140,6 +146,9 @@ - (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSStrin
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
if (!self.isFCMEnabled) {
return;
}
[FIRMessaging messaging].APNSToken = deviceToken;
[FirebasePlugin.firebasePlugin _logMessage:[NSString stringWithFormat:@"didRegisterForRemoteNotificationsWithDeviceToken: %@", deviceToken]];
[FirebasePlugin.firebasePlugin sendApnsToken:[FirebasePlugin.firebasePlugin hexadecimalStringFromData:deviceToken]];
Expand All @@ -150,6 +159,10 @@ - (void)application:(UIApplication *)application didRegisterForRemoteNotificatio
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

if (!self.isFCMEnabled) {
return;
}

@try{
[[FIRMessaging messaging] appDidReceiveMessage:userInfo];
mutableUserInfo = [userInfo mutableCopy];
Expand Down Expand Up @@ -295,6 +308,9 @@ -(void)processMessageForForegroundNotification:(NSDictionary*)messageData {
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
if (!self.isFCMEnabled) {
return;
}
[FirebasePlugin.firebasePlugin _logError:[NSString stringWithFormat:@"didFailToRegisterForRemoteNotificationsWithError: %@", error.description]];
}

Expand All @@ -316,12 +332,14 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center

@try{

if (![notification.request.trigger isKindOfClass:UNPushNotificationTrigger.class] && ![notification.request.trigger isKindOfClass:UNTimeIntervalNotificationTrigger.class]){
if (_previousDelegate) {
if (![notification.request.trigger isKindOfClass:UNPushNotificationTrigger.class] && ![notification.request.trigger isKindOfClass:UNTimeIntervalNotificationTrigger.class]) {
if (_prevUserNotificationCenterDelegate) {
// bubbling notification
[_previousDelegate userNotificationCenter:center
willPresentNotification:notification
withCompletionHandler:completionHandler];
[_prevUserNotificationCenterDelegate
userNotificationCenter:center
willPresentNotification:notification
withCompletionHandler:completionHandler
];
return;
} else {
[FirebasePlugin.firebasePlugin _logError:@"willPresentNotification: aborting as not a supported UNNotificationTrigger"];
Expand Down Expand Up @@ -392,12 +410,14 @@ - (void) userNotificationCenter:(UNUserNotificationCenter *)center
{
@try{

if (![response.notification.request.trigger isKindOfClass:UNPushNotificationTrigger.class] && ![response.notification.request.trigger isKindOfClass:UNTimeIntervalNotificationTrigger.class]){
if (_previousDelegate) {
if (![response.notification.request.trigger isKindOfClass:UNPushNotificationTrigger.class] && ![response.notification.request.trigger isKindOfClass:UNTimeIntervalNotificationTrigger.class]) {
if (_prevUserNotificationCenterDelegate) {
// bubbling event
[_previousDelegate userNotificationCenter:center
didReceiveNotificationResponse:response
withCompletionHandler:completionHandler];
[_prevUserNotificationCenterDelegate
userNotificationCenter:center
didReceiveNotificationResponse:response
withCompletionHandler:completionHandler
];
return;
} else {
[FirebasePlugin.firebasePlugin _logMessage:@"didReceiveNotificationResponse: aborting as not a supported UNNotificationTrigger"];
Expand Down
2 changes: 2 additions & 0 deletions src/ios/FirebasePlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@
- (void)deleteChannel:(CDVInvokedUrlCommand *)command;
- (void)listChannels:(CDVInvokedUrlCommand *)command;

@property (nonatomic, readonly) BOOL isFCMEnabled;

@property (nonatomic, copy) NSString *notificationCallbackId;
@property (nonatomic, copy) NSString *openSettingsCallbackId;
@property (nonatomic, copy) NSString *tokenRefreshCallbackId;
Expand Down
52 changes: 38 additions & 14 deletions src/ios/FirebasePlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ @implementation FirebasePlugin
static NSString*const FirebaseCrashlyticsCollectionEnabled = @"FirebaseCrashlyticsCollectionEnabled"; //plist
static NSString*const FIREBASE_ANALYTICS_COLLECTION_ENABLED = @"FIREBASE_ANALYTICS_COLLECTION_ENABLED";
static NSString*const FIREBASE_PERFORMANCE_COLLECTION_ENABLED = @"FIREBASE_PERFORMANCE_COLLECTION_ENABLED";
static NSString*const FIREBASEX_IOS_FCM_ENABLED = @"FIREBASEX_IOS_FCM_ENABLED";

static FirebasePlugin* firebasePlugin;
static BOOL registeredForRemoteNotifications = NO;
Expand Down Expand Up @@ -86,13 +87,20 @@ - (void)pluginInitialize {
if([self getGooglePlistFlagWithDefaultValue:FIREBASE_PERFORMANCE_COLLECTION_ENABLED defaultValue:YES]){
[self setPreferenceFlag:FIREBASE_PERFORMANCE_COLLECTION_ENABLED flag:YES];
}

// We don't need `setPreferenceFlag` here as we don't allow to change this at runtime.
_isFCMEnabled = [self getGooglePlistFlagWithDefaultValue:FIREBASEX_IOS_FCM_ENABLED defaultValue:YES];
if (!self.isFCMEnabled) {
[self _logInfo:@"Firebase Cloud Messaging is disabled, see IOS_FCM_ENABLED variable of the plugin"];
}

// Set actionable categories if pn-actions.json exist in bundle
[self setActionableNotifications];

// Check for permission and register for remote notifications if granted
[self _hasPermission:^(BOOL result) {}];

if (self.isFCMEnabled) {
[self _hasPermission:^(BOOL result) {}];
}

authCredentials = [[NSMutableDictionary alloc] init];
firestoreListeners = [[NSMutableDictionary alloc] init];
Expand All @@ -102,10 +110,27 @@ - (void)pluginInitialize {
}
}


// Dynamic actions from pn-actions.json
- (void)setActionableNotifications {

@try {

// Initialize installation ID change listener
__weak __auto_type weakSelf = self;
self.installationIDObserver = [[NSNotificationCenter defaultCenter]
addObserverForName: FIRInstallationIDDidChangeNotification
object:nil
queue:nil
usingBlock:^(NSNotification * _Nonnull notification) {
[weakSelf sendNewInstallationId];
}
];

// The part related to installation ID is not specific to FCM, that's why it was moved above.
if (!self.isFCMEnabled) {
return;
}

// Parse JSON
NSString *path = [[NSBundle mainBundle] pathForResource:@"pn-actions" ofType:@"json"];
NSData *data = [NSData dataWithContentsOfFile:path];
Expand Down Expand Up @@ -144,16 +169,7 @@ - (void)setActionableNotifications {

// Initialize categories
[[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:categories];

// Initialize installation ID change listner
__weak __auto_type weakSelf = self;
self.installationIDObserver = [[NSNotificationCenter defaultCenter]
addObserverForName: FIRInstallationIDDidChangeNotification
object:nil
queue:nil
usingBlock:^(NSNotification * _Nonnull notification) {
[weakSelf sendNewInstallationId];
}];

}@catch (NSException *exception) {
[self handlePluginExceptionWithoutContext:exception];
}
Expand Down Expand Up @@ -416,6 +432,7 @@ - (void)grantCriticalPermission:(CDVInvokedUrlCommand *)command {

- (void)registerForRemoteNotifications {
NSLog(@"registerForRemoteNotifications");

if(registeredForRemoteNotifications) return;

[self runOnMainThread:^{
Expand Down Expand Up @@ -2820,7 +2837,13 @@ - (BOOL) getGooglePlistFlagWithDefaultValue:(NSString*) name defaultValue:(BOOL)
if([googlePlist objectForKey:name] == nil){
return defaultValue;
}
return [[googlePlist objectForKey:name] isEqualToString:@"true"];
id value = [googlePlist objectForKey:name];
if ([value isKindOfClass:[NSNumber class]]) {
return [value boolValue];
} else {
// Note that `isEqualToString` would crash if the value is not a string.
return [value isEqual:@"true"];
}
}


Expand Down Expand Up @@ -2852,4 +2875,5 @@ - (void)listChannels:(CDVInvokedUrlCommand *)command {
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}];
}

@end

0 comments on commit b47eb31

Please sign in to comment.