12

Description of the issue:

I'm implementing push notification in my React-Native app using this AWS Amplify doc and testing with the iOS part fails with the error "Invariant Violation: Native module cannot be null", however if I test (i.e fetching device token and sending push notification) the Android part it works. Screenshot of the error I see on the iOS is seen below :

enter image description here

What I have tried so far :

  1. Upgrading react-native version from 0.59.10 to 0.61.5
  2. As per this github post, I also tried installing the following:

    @react-native-community/push-notification-ios

    npm install aws-amplify@unstable

This module (aws-amplify@unstable) introduced an error saying TypeError: undefined is not an object (evaluating '_core.Amplify.register') so I decided to get rid of it.

  1. Using latest package of "@aws-amplify/pushnotification": "^3.0.13" works for Android but in iOS I'm back to the original error : "Invariant Violation: Native module cannot be null"

currently I've left my package.json as follows :

"dependencies": {
"@aws-amplify/pushnotification": "^1.1.4",
"@aws-amplify/analytics": "^1.3.3",
"@react-native-community/netinfo": "^5.7.0",
"@react-native-community/push-notification-ios": "^1.2.0",
"amazon-cognito-identity-js": "^4.2.1",
"aws-amplify": "^1.2.4",
"aws-amplify-react-native": "^4.2.0",
"axios": "^0.19.2",
"cache": "^2.3.1",
"react": "16.9.0",
"react-native": "^0.62.2"
}

Let me get some sleep, I'll continue debugging tomorrow morning ..

aksyuma
  • 2,957
  • 1
  • 15
  • 29

1 Answers1

7

After hours of debugging it appears some versions don't play well with each-other and I've managed to fix the error "Invariant Violation: Native module cannot be null" and get Android & iOS push notification working using the following version aws amplify lib and @react-native-community/push-notification-ios:

"dependencies": {
"@aws-amplify/pushnotification": "^3.0.13",
"@aws-amplify/analytics": "^1.3.3",
"@react-native-community/netinfo": "^5.7.0",
"@react-native-community/push-notification-ios": "^1.0.2",
"amazon-cognito-identity-js": "^4.2.1",
"aws-amplify": "^3.0.13",
"aws-amplify-react-native": "^4.2.0",
"axios": "^0.19.2",
"cache": "^2.3.1",
"react": "16.9.0",
"react-native": "^0.62.2"
},

or

"dependencies": {
"@react-native-community/push-notification-ios": "^1.2.0",
"@react-native-community/netinfo": "^5.7.0",
"@aws-amplify/pushnotification": "^3.1.2",
"@aws-amplify/analytics": "^1.3.3",
"@aws-amplify/core": "^3.3.2",
"amazon-cognito-identity-js": "^4.2.1",
"aws-amplify-react-native": "^4.2.0",
"aws-amplify": "^3.0.16",
"axios": "^0.19.2",
"cache": "^2.3.1",
"react": "16.9.0",
"react-native": "^0.62.2"
},

It appears AWS Amplify (push notification module for iOS) has switched from react-native core to @react-native-community/push-notification-ios. Therefore, here's some changes due to this migration which one might need to cross-check incase you run into this issue :

Step 1 : Update Podfile

Remove 'React-RCTPushNotification' from your Podfile (which you can find in ios folder).:

pod 'React-RCTPushNotification', :path => '../node_modules/react-native/Libraries/PushNotificationIOS'

Step 2: Link the PushNotificationIOS library

Step 2.1 : Automatic Linking

Add the following RNCPushNotificationIOS to your podfile (which you can find in ios folder).

pod 'RNCPushNotificationIOS', :path => '../node_modules/@react-native-community/push-notification-ios/RNCPushNotificationIOS.podspec'

And then install pod dependencies by running following command: cd ios && pod install

Step 2.2 : Manual Linking (if Auto linking doesn't work for you consider this option)

Drag this PushNotificationIOS.xcodeproj file (node_modules/@react-native-community/push-notification-ios/ios) to your project on Xcode (usually under the Libraries group on Xcode):

enter image description here

Add libRNCPushNotificationIOS.a into your linked Binaries by selecting Project Navigator -> Target -> Build Phrases -> Linked Binary with Libraries (make sure libRNCPushNotificationIOS.a is there)

enter image description here enter image description here

Step 3 : Augment AppDelegate

Step 3.1 : Update AppDelegate.h

At the top of the file add the following :

#import <UserNotifications/UNUserNotificationCenter.h>

Then, add the 'UNUserNotificationCenterDelegate' to protocols as shown below :

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

Step 3.2 : Update AppDelegate.m

At the top of the file add the following :

#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>

Replace all entries in your AppDelegate.m for RCTPushNotificationManager with RNCPushNotificationIOS

Then, add the following code snippet just before @end as per react-native-community.push-notification-ios

// Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
  [RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings];
}
// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
  [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event. You must call the completion handler after handling the remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
  [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
// Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
  [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}
// Required for the localNotification event.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
  [RNCPushNotificationIOS didReceiveLocalNotification:notification];
}

Other helpful Tips!

whenever you update your package.json, do the following :

rm -rf -rf node_modules
yarn cache clean --force
yarn install
cd ios && pod install
React-native start -- --reset-cache

Hope this helps someone!

aksyuma
  • 2,957
  • 1
  • 15
  • 29