Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[馃悰] (Automated/Scheduled) Push Notifications NOT working in iOS #7796

Open
1 of 6 tasks
nl-danish opened this issue May 17, 2024 · 1 comment
Open
1 of 6 tasks
Labels
Workflow: Waiting for User Response Blocked waiting for user response.

Comments

@nl-danish
Copy link

nl-danish commented May 17, 2024

Issue

Hi @mikehardy,

Addressing the previous old issues i've raised (#7784 ,#7589 ,#7783)

We have now upgraded our react native firebase packages, we've changed our AppDeletegate file according to the doc, and we've also cross checked APNs key and cross checked sending Manual notification to our iOS project from Dashboard and Postman cURL request, this works fine.

Basically, we've tried to skimmed through all the documentation and issues we could find, but still we are failing with our push notifications for our iOS devices which used to send earlier from our backend server whenever any new thing (shows or articles) are published, another thing to note is where our Notification type is message.

Please, could anyone guide us what's happening wrong? Please, let us know, we're in a dead loop of no solutions.

This is our notification block that we're sending from backend,

 send_notification.delay({
                'device_token': token_detail['device_token'],
                'title': notification_info[token_detail['language']]['title'],
                'message': notification_info[token_detail['language']]['message'],
                'data_message': {
                    'podcast_id': meta_data['episode_id'],
                    'event_type': 'new_podcast_published',
                    'icon_url': meta_data['image']
                },
                'extra_notification_kwargs': {
                    'image': meta_data['image']
                },
                'message_icon': meta_data['image']
            })

And, this is the function

def send_notification(params):
    """
    Send notification to user device
    """
    logger.info(params)
    push_notification_service.notify_single_device(registration_id=params['device_token'], message_title=params['title'],
                                                   message_body=params['message'], data_message=params['data_message'], low_priority=False, sound='Default', content_available=True, android_channel_id='default-channel-id', extra_notification_kwargs=params['extra_notification_kwargs'], message_icon=params['message_icon'], extra_kwargs={'mutable_content': True})

Thanks.


Project Files

Javascript

Click To Expand

package.json:

    "@react-native-firebase/analytics": "^15.3.0",
    "@react-native-firebase/app": "^15.3.0",
    "@react-native-firebase/crashlytics": "^15.3.0",
    "@react-native-firebase/in-app-messaging": "^15.3.0",
    "@react-native-firebase/messaging": "^15.3.0",

firebase.json:

{
  "react-native": {
    "messaging_android_notification_channel_id": "high-priority",
    "crashlytics_auto_collection_enabled": true,
    "crashlytics_debug_enabled": false
  }
}

iOS

Click To Expand

ios/Podfile:

  • I'm not using Pods
  • I'm using Pods and my Podfile looks like:
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

$RNFirebaseAsStaticFramework = true


platform :ios, '11.0'

target 'NewsLaundry' do
  use_frameworks!

  config = use_native_modules!

  use_react_native!(
    :path => config[:reactNativePath],
    # to enable hermes on iOS, change `false` to `true` and then install pods
    :hermes_enabled => false,
  )

  # Permissions
  permissions_path = '../node_modules/react-native-permissions/ios'
  pod 'Permission-LocationAlways', :path => "#{permissions_path}/LocationAlways/Permission-LocationAlways.podspec"
  pod 'Permission-LocationWhenInUse', :path => "#{permissions_path}/LocationWhenInUse/Permission-LocationWhenInUse.podspec"
  pod 'Permission-PhotoLibrary', :path => "#{permissions_path}/PhotoLibrary"
  pod 'react-native-onesignal', :path => '../node_modules/react-native-onesignal'
  # React Native Version Check (for iOS app updates)
  pod 'react-native-version-check', :path => '../node_modules/react-native-version-check'
  pod 'react-native-segmented-control', :path => '../node_modules/@react-native-segmented-control/segmented-control'
  pod 'ReactNativeMoEngage', :path => '../node_modules/react-native-moengage'
  pod 'ReactNativeMoEngage', :path => '../node_modules/react-native-moengage'
  pod 'react-native-voice', :path => '../node_modules/@react-native-voice/voice'
  pod 'GoogleUtilities'

  target 'NewsLaundryTests' do
    use_frameworks!

    inherit! :complete
    # Pods for testing
  end

  # Enables Flipper.
  #
  # Note that if you have use_frameworks! enabled, Flipper will not work and
  # you should disable the next line.
  # use_flipper!()

  pre_install do |installer|
    Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {}
  
    installer.pod_targets.each do |pod|
      if pod.name.eql?('RNPermissions') || pod.name.start_with?('Permission-')
        def pod.build_type;
          Pod::BuildType.static_library
        end
      end
    end
  end

  post_install do |installer|
    react_native_post_install(installer)
  end
end

target 'ImageNotification' do
  use_frameworks!
  pod 'Firebase/Messaging', '~> 9.4.0' # Version should match the podfile.lock version Refer https://rnfirebase.io/messaging/ios-notification-images
  pod 'GoogleUtilities'
end

target 'OneSignalNotificationServiceExtension' do
  use_frameworks!
  pod 'OneSignalXCFramework', '>= 3.4.3', '< 4.0'
  pod 'GoogleUtilities'
end

AppDelegate.m:

#import "AppDelegate.h"

#import "RNSplashScreen.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTLinkingManager.h>
#import <Firebase.h>
#import <RNBackgroundDownloader.h>
#import <RNFBMessagingModule.h>
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <CodePush/CodePush.h>
#import <ReactNativeMoEngage/MoEngageInitializer.h>
#import <MoEngageSDK/MoEngageSDK.h>
#import "Orientation.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = self;
    
    // Request authorization for notifications
    UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
    [center requestAuthorizationWithOptions:authOptions
                          completionHandler:^(BOOL granted, NSError * _Nullable error) {
                              // ...
                          }];

    // Register for remote notifications
    [application registerForRemoteNotifications];
    
    if ([FIRApp defaultApp] == nil) {
        [FIRApp configure];
    }

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

    [[FIRMessaging messaging] tokenWithCompletion:^(NSString *token, NSError *error) {
  if (error != nil) {
    NSLog(@"Error getting FCM registration token: %@", error);
  } else {
    NSLog(@"FCM registration token: %@", token);
    // self.fcmRegTokenMessage.text = token;
  }
}];


    [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];

    RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
    NSDictionary *appProperties = [RNFBMessagingModule addCustomPropsToUserProps:nil withLaunchOptions:launchOptions];
    RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                     moduleName:@"NewsLaundry"
                                              initialProperties:appProperties];

    if (@available(iOS 13.0, *)) {
        rootView.backgroundColor = [UIColor systemBackgroundColor];
    } else {
        rootView.backgroundColor = [UIColor whiteColor];
    }

    [[MoEngageInitializer sharedInstance] initializeDefaultInstance:launchOptions];

    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    UIViewController *rootViewController = [UIViewController new];
    rootViewController.view = rootView;
    self.window.rootViewController = rootViewController;
    [self.window makeKeyAndVisible];

    [FIRMessaging messaging].autoInitEnabled = YES;

    // [RNSplashScreen show];
    return YES;
}

- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    while ([[UIDevice currentDevice] isGeneratingDeviceOrientationNotifications]) {
        [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
    }
    return [Orientation getOrientation];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    // Pass in UIBackgroundFetchResult based on whether operation was successful or has failed
    completionHandler(UIBackgroundFetchResultNewData);
}

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
    [FIRMessaging messaging].APNSToken = deviceToken;
    [[MoEngageSDKMessaging sharedInstance] setPushToken:deviceToken];
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    [[MoEngageSDKMessaging sharedInstance] didFailToRegisterForPush];
}

- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken {
    NSLog(@"FCM registration token: %@", fcmToken);
    // Notify about received token.
    NSDictionary *dataDict = [NSDictionary dictionaryWithObject:fcmToken forKey:@"token"];
    [[NSNotificationCenter defaultCenter] postNotificationName:
     @"FCMToken" object:nil userInfo:dataDict];
    // TODO: If necessary send token to application server.
    // Note: This callback is fired at each app startup and whenever a new token is generated.
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void (^)())completionHandler {
    // Call only if MoEngageAppDelegateProxyEnabled is NO
    [[MoEngageSDKMessaging sharedInstance] userNotificationCenter:center didReceive:response];
    // Custom Handling of notification if Any
    completionHandler();
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
       willPresentNotification:(UNNotification *)notification
         withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
    // This is to only to display Alert and enable notification sound
    completionHandler((UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert));
}

- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    BOOL handledFB = [[FBSDKApplicationDelegate sharedInstance] application:app openURL:url options:options];
    BOOL handledDeeplinking = [RCTLinkingManager application:app openURL:url options:options];
    return handledFB || handledDeeplinking;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
#if DEBUG
    return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
    return [CodePush bundleURL];
#endif
}

- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)(void))completionHandler {
    [RNBackgroundDownloader setCompletionHandlerWithIdentifier:identifier completionHandler:completionHandler];
}

- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
 restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
    return [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
}

- (BOOL)application:(UIApplication *)application shouldSaveSecureApplicationState:(NSCoder *)coder {
    return YES;
}

- (BOOL)application:(UIApplication *)application shouldRestoreSecureApplicationState:(NSCoder *)coder {
    return YES;
}

@end


Environment

Click To Expand

react-native info output:

 System:
OS: macOS 13.3.1
CPU: (8) arm64 Apple M1
Memory: 113.25 MB / 8.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 18.16.0 - /opt/homebrew/opt/node@18/bin/node
Yarn: 1.22.19 - /opt/homebrew/bin/yarn
npm: 9.5.1 - /opt/homebrew/opt/node@18/bin/npm
Watchman: 2023.05.22.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: 1.12.1 - /Users/appName/.rvm/gems/ruby-2.7.6/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 22.1, iOS 16.1, macOS 13.0, tvOS 16.1, watchOS 9.1
Android SDK: Not Found
IDEs:
Android Studio: 2022.2 AI-222.4459.24.2221.9971841
Xcode: 14.1/14B47b - /usr/bin/xcodebuild
Languages:
Java: 11.0.19 - /usr/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: ^17.0.2 => 17.0.2
react-native: ^0.66.5 => 0.66.5
react-native-macos: Not Found
npmGlobalPackages:
react-native: Not Found
  • Platform that you're experiencing the issue on:
    • [ x] iOS
    • Android
    • iOS but have not tested behavior on Android
    • Android but have not tested behavior on iOS
    • Both
 "@react-native-firebase/analytics": "^15.3.0"
"@react-native-firebase/app": "^15.3.0"
"@react-native-firebase/crashlytics": "^15.3.0"
"@react-native-firebase/in-app-messaging": "^15.3.0"
"@react-native-firebase/messaging": "^15.3.0"
"react-native": "^0.66.5"
  • Are you using TypeScript?
    • `No


@nl-danish nl-danish added Help: Needs Triage Issue needs additional investigation/triaging. Impact: Bug New bug report labels May 17, 2024
@mikehardy
Copy link
Collaborator

It appears there is no "notification" key in the FCM you are sending.
Those are unreliable and I would expect they won't be delivered.
You're at the mercy of Apple and any changes they make to iOS (which changes in my experience just reduce delivery of data-only message further)

Please test after modifying your send method to include a notification key and report results

@mikehardy mikehardy added Workflow: Waiting for User Response Blocked waiting for user response. and removed Impact: Bug New bug report Help: Needs Triage Issue needs additional investigation/triaging. labels May 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Workflow: Waiting for User Response Blocked waiting for user response.
Projects
None yet
Development

No branches or pull requests

2 participants