react-native-push-notification / ios

React Native Push Notification API for iOS.
MIT License
731 stars 280 forks source link

Not able to receive remote notification #401

Open CarloTamburrelli opened 1 year ago

CarloTamburrelli commented 1 year ago

Hi, I'm totally lost. I can't receive push notifications via the IOS simulator but I can receive the notification in Android. Here are the steps I took:

#import <React/RCTBridgeDelegate.h>
#import <UIKit/UIKit.h>
#import <UserNotifications/UNUserNotificationCenter.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate>

@property (nonatomic, strong) UIWindow *window;

@end

import <React/RCTBridge.h>

import <React/RCTBundleURLProvider.h>

import <React/RCTRootView.h>

import

import <React/RCTAppSetupUtils.h>

import <UserNotifications/UserNotifications.h>

import

import <FBSDKCoreKit/FBSDKCoreKit.h>

if RCT_NEW_ARCH_ENABLED

import <React/CoreModulesPlugins.h>

import <React/RCTCxxBridgeDelegate.h>

import <React/RCTFabricSurfaceHostingProxyRootView.h>

import <React/RCTSurfacePresenter.h>

import <React/RCTSurfacePresenterBridgeAdapter.h>

import <ReactCommon/RCTTurboModuleManager.h>

import <react/config/ReactNativeConfig.h>

static NSString *const kRNConcurrentRoot = @"concurrentRoot";

@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> { RCTTurboModuleManager _turboModuleManager; RCTSurfacePresenterBridgeAdapter _bridgeAdapter; std::shared_ptr _reactNativeConfig; facebook::react::ContextContainer::Shared _contextContainer; } @end

endif

@implementation AppDelegate

// Required for the register event.

if RCT_NEW_ARCH_ENABLED

_contextContainer = std::make_shared(); _reactNativeConfig = std::make_shared(); _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer]; bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;

endif

NSDictionary initProps = [self prepareInitialProps]; UIView rootView = RCTAppSetupDefaultRootView(bridge, @"nuovozizi", initProps);

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

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

// Define UNUserNotificationCenter UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = self;

return YES; }

//Called when a notification is delivered to a foreground app. -(void)userNotificationCenter:(UNUserNotificationCenter )center willPresentNotification:(UNNotification )notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge); }

/// This method controls whether the concurrentRootfeature of React18 is turned on or off. /// /// @see: https://reactjs.org/blog/2022/03/29/react-v18.html /// @note: This requires to be rendering on Fabric (i.e. on the New Architecture). /// @return: true if the concurrentRoot feture is enabled. Otherwise, it returns false.

ifdef RCT_NEW_ARCH_ENABLED

initProps[kRNConcurrentRoot] = @([self concurrentRootEnabled]);

endif

return initProps; }

if RCT_NEW_ARCH_ENABLED

pragma mark - RCTCxxBridgeDelegate

pragma mark RCTTurboModuleManagerDelegate

endif

@end

- I added also the capability in Xcode (Background Mode[remote notification] and Push notifications)
- i subscribe with my bundle id the app on Firebase
- I added the APNs token on Firebase
- I added the GoogleService-info on the project
- I register the APP ID (with my bundle id app) on the developer apple account

- client part:
``` javascript
 PushNotification.configure({
      // Called when Token is generated.
      onRegister: function (token) {
        console.log('token:', token);
       // Register ur remote notificaiton to listen to
      },

      // Called when a remote or local notification is opened or received.
      onNotification: function (notification) {
        console.log('NOTIFICATION:----REMOTE', notification);
        console.log(notification.data.type);
        PushNotification.cancelAllLocalNotifications();
        console.log('NO Push', notification);

        //   .then((url) => console.log('Hello uRl', url))
        //   .catch((err) => console.log(err));
        // Do something with the notification.
        // Required on iOS only (see fetchCompletionHandler docs: https://reactnative.dev/docs/pushnotificationios)
        notification.finish(PushNotificationIOS.FetchResult.NoData);
      },
      // (optional) Called when Registered Action is pressed and invokeApp is false, if true onNotification will be called (Android)
      onAction: function (notification) {
        console.log('ACTION:', notification.action);
        console.log('NOTIFICATIONS:', notification);

        // PushNotification.getChannels(function (channel_ids) {
        //   console.log('Channel ID', channel_ids); // ['channel_id_1']
        // });

        // process the action
      },

      // (optional) Called when the user fails to register for remote notifications. Typically occurs when APNS is having issues, or the device is a simulator. (iOS)
      onRegistrationError: function (err) {
        console.log('THis is the error registering notification', err);
        console.error(err.message, err);
      },

      // IOS ONLY (optional): default: all - Permissions to register.
      permissions: {
        alert: true,
        badge: true,
        sound: true,
      },

      // Should the initial notification be popped automatically
      // default: true
      popInitialNotification: true,

      /**
       * (optional) default: true
       * - Specified if permissions (ios) and token (android and ios) will requested or not,
       * - if not, you must call PushNotificationsHandler.requestPermissions() later
       * - if you are not using remote notification or do not have Firebase installed, use this:
       *     requestPermissions: Platform.OS === 'ios'
       */
      requestPermissions: true,
    });

PS: is it sufficient to receive push notifications in the client part? Or i need to integrate another libs?

with this code I am able to take the user token:

 token: {"os": "ios", "token": "80168a7e774afb1a7a4cf892b0..."}

Server side:

I use this token in the server part like this:

Where am I wrong? In which of these steps am I doing something wrong?

vpawar3 commented 1 year ago

iOS simulator not supported to Push notification. If you want to test you need to check on real iOS device.

CarloTamburrelli commented 1 year ago

iOS simulator not supported to Push notification. If you want to test you need to check on real iOS device.

Ok thanks for the reply, I'll take a real device.

Can you tell me if the request from the server and client side with react native I make is correct? Thanks

CarloTamburrelli commented 1 year ago

Guys i managed to get the push notification working finally (with a real device), for IOS it was necessary to add the "notification" field, and using it as the "data" for android, so:

{
 "registration_ids": ["ejXQlECjCeI:APA91bE7oaUhaFnGyl77lFrySdEaWxocM0oj81uNezACX1wsZXiTyL4OYo5ssvFjjWYpFymMVyqBccboVcwTTW2rvykOmV_CABDM7rTIRCiJFl_9ngf7SrDSYoFouwNj69JSwlH....."],
 "data": {
   "title": "Breaking News",
   "message": "New Story available."
 }, 
"notification": { // only for ios devices
   "title": "Breaking News",
   "message": "New Story available."
 },
 "priority":"high"
}

This will trigger the onNotification on react native like a charm!

Very important: I use a M1 MacBook Air and also for the simulator the push notification are working (not just real device). The only problem so was the missing notification field in the request.

ninjia0 commented 8 months ago

Guys i managed to get the push notification working finally (with a real device), for IOS it was necessary to add the "notification" field, and using it as the "data" for android, so:

{
 "registration_ids": ["ejXQlECjCeI:APA91bE7oaUhaFnGyl77lFrySdEaWxocM0oj81uNezACX1wsZXiTyL4OYo5ssvFjjWYpFymMVyqBccboVcwTTW2rvykOmV_CABDM7rTIRCiJFl_9ngf7SrDSYoFouwNj69JSwlH....."],
 "data": {
   "title": "Breaking News",
   "message": "New Story available."
 }, 
"notification": { // only for ios devices
   "title": "Breaking News",
   "message": "New Story available."
 },
 "priority":"high"
}

This will trigger the onNotification on react native like a charm!

Very important: I use a M1 MacBook Air and also for the simulator the push notification are working (not just real device). The only problem so was the missing notification field in the request. where should i add this notification? i am using firebase console, there is no option to add notification?