amplify-js: Sometimes App doesn't Open on android after click on notification

Before opening, please confirm:

JavaScript Framework

React Native

Amplify APIs

Analytics, Push Notifications

Amplify Categories

notifications

Environment information

# Put output below this line

System:
    OS: macOS 12.2.1
    CPU: (8) x64 Apple M1
    Memory: 22.57 MB / 8.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 14.16.0 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 7.24.2 - ~/Desktop/Villeo/node_modules/.bin/npm
    Watchman: 2022.03.21.00 - /opt/homebrew/bin/watchman
  npmPackages:
    @aws-amplify/pushnotification: ^4.1.3 => 4.2.14
    @babel/core: ^7.13.16 => 7.15.8
    @babel/runtime: ^7.13.17 => 7.15.4
    @mdi/js: ^5.9.55 => 5.9.55
    @mdi/react: ^1.5.0 => 1.5.0
    @react-native-async-storage/async-storage: ^1.15.4 => 1.15.9
    @react-native-community/eslint-config: ^2.0.0 => 2.0.0
    @react-native-community/netinfo: ^6.2.1 => 6.2.1
    @react-native-community/progress-bar-android: ^1.0.4 => 1.0.4
    @react-native-community/progress-view: ^1.3.1 => 1.3.1
    @react-native-community/push-notification-ios: ^1.0.3 => 1.10.1 (1.0.3)
    @react-native-picker/picker: ^1.15.0 => 1.16.8
    @react-native/normalize-color: ^2.0.0 => 2.0.0 (1.0.0)
    @react-navigation/bottom-tabs: ^5.11.10 => 5.11.15
    @react-navigation/drawer: ^5.12.5 => 5.12.9
    @react-navigation/native: ^5.9.4 => 5.9.8
    @react-navigation/stack: ^5.14.4 => 5.14.9
    Basic:  0.0.1
    HelloWorld:  0.0.1
    PDFExample:  0.0.1
    amazon-cognito-identity-js: ^4.6.0 => 4.6.3 (5.2.0)
    aws-amplify: ^4.3.1 => 4.3.2
    aws-amplify-react-native: ^4.3.2 => 4.3.3
    aws-sdk: ^2.946.0 => 2.1005.0
    babel-jest: ^26.6.3 => 26.6.3
    eslint: 7.25.0 => 7.25.0
    hermes-inspector-msggen:  1.0.0
    install: ^0.13.0 => 0.13.0
    jest: ^26.6.3 => 26.6.3
    lodash: ^4.17.21 => 4.17.21
    metro: ^0.66.0 => 0.66.2 (0.64.0)
    metro-config: ^0.66.0 => 0.66.2 (0.64.0)
    metro-react-native-babel-preset: ^0.66.0 => 0.66.2 (0.64.0)
    moment: ^2.29.1 => 2.29.1
    npm: ^7.11.1 => 7.24.2
    npm-check-updates: ^11.5.4 => 11.8.5
    react: 17.0.2 => 17.0.2
    react-native: 0.64.0 => 0.64.0
    react-native-action-button: ^2.8.5 => 2.8.5
    react-native-calendars: ^1.1259.0 => 1.1267.0
    react-native-customized-image-picker: ^1.2.1 => 1.2.2
    react-native-dropdown-picker: ^4.0.9 => 4.0.9
    react-native-elements: ^3.4.2 => 3.4.2
    react-native-fast-image: ^8.5.11 => 8.5.11
    react-native-gesture-handler: ^1.10.3 => 1.10.3
    react-native-get-location: ^2.1.1 => 2.1.2
    react-native-get-random-values: ^1.7.0 => 1.7.0
    react-native-image-picker: ^3.8.1 => 3.8.1
    react-native-image-zoom-viewer: ^3.0.1 => 3.0.1
    react-native-loading-spinner-overlay: ^3.0.0 => 3.0.0
    react-native-maps: ^0.30.2 => 0.30.2
    react-native-pdf: ^6.3.0 => 6.3.0
    react-native-permissions: ^3.0.5 => 3.0.5
    react-native-push-notification: ^8.1.1 => 8.1.1
    react-native-rate: ^1.2.9 => 1.2.9
    react-native-reanimated: ^2.1.0 => 2.2.2
    react-native-render-html: ^6.0.4 => 6.1.0
    react-native-safe-area-context: ^3.4.1 => 3.4.1
    react-native-screens: ^3.1.1 => 3.8.0
    react-native-share: ^7.3.3 => 7.3.3
    react-native-snap-carousel: ^3.9.1 => 3.9.1
    react-native-splash-screen: ^3.2.0 => 3.2.0
    react-native-svg: ^12.1.1 => 12.3.0
    react-native-svg-transformer: ^0.14.3 => 0.14.3
    react-native-tip: ^0.0.18 => 0.0.18
    react-native-vector-icons: ^8.1.0 => 8.1.0 (7.1.0)
    react-native-video: ^5.2.0 => 5.2.0
    react-native-video-player: ^0.12.0 => 0.12.0
    react-native-webview: ^11.17.2 => 11.17.2
    react-redux: ^7.2.4 => 7.2.5
    react-test-renderer: 17.0.2 => 17.0.2
    react-xml-parser: ^1.1.8 => 1.1.8
    redux: ^4.1.0 => 4.1.1
    redux-persist: ^6.0.0 => 6.0.0
    redux-persist/integration/react:  undefined ()
    rn-fetch-blob: ^0.12.0 => 0.12.0
    svg-path-bbox: ^1.0.1 => 1.0.1
    uuid: ^8.3.2 => 8.3.2 (3.4.0, 3.3.2)
  npmGlobalPackages:
    @aws-amplify/cli: 7.6.26
    aws-amplify-react-native: 5.0.1
    aws-amplify: 4.0.3
    expo-cli: 4.3.2
    graphql: 14.7.0
    ios-deploy: 1.11.4
    npm-check-updates: 11.5.4
    npm: 7.6.3
    react-native-cli: 2.0.1
    yarn: 1.22.10



Describe the bug

Sometimes when a user receives a notification, clicking on it does nothing even though it is supposed to open app.

This is not really frequent hovewer we are trying to solve this issue.

Expected behavior

The application should open, using a deep link or just starting its normal way

Reproduction steps

As i said this bug is really infrequent, i beleive it happens only on certains models (see below)

i haven’t been able to reproduce it on my devices.

https://user-images.githubusercontent.com/61412031/181234459-35587090-5f9e-4294-8cbd-8fb735fb157d.mp4

Code Snippet

// Put your code below this line.

Log output

Here are the logs that google play console provides me :

java.lang.RuntimeException: 
  at android.app.ActivityThread.handleReceiver (ActivityThread.java:4358)
  at android.app.ActivityThread.access$2500 (ActivityThread.java:296)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2238)
  at android.os.Handler.dispatchMessage (Handler.java:107)
  at android.os.Looper.loop (Looper.java:213)
  at android.app.ActivityThread.main (ActivityThread.java:8178)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:513)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1101)
Caused by: java.lang.NullPointerException: 
  at com.amazonaws.amplify.pushnotification.modules.RNPushNotificationJsDelivery.sendEvent (RNPushNotificationJsDelivery.java:2)
  at com.amazonaws.amplify.pushnotification.modules.RNPushNotificationJsDelivery.emitNotificationOpened (RNPushNotificationJsDelivery.java:37)
  at com.amazonaws.amplify.pushnotification.modules.RNPushNotificationBroadcastReceiver.onReceive (RNPushNotificationBroadcastReceiver.java:38)
  at android.app.ActivityThread.handleReceiver (ActivityThread.java:4349)
  at android.app.ActivityThread.access$2500 (ActivityThread.java:296)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2238)
  at android.os.Handler.dispatchMessage (Handler.java:107)
  at android.os.Looper.loop (Looper.java:213)
  at android.app.ActivityThread.main (ActivityThread.java:8178)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:513)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1101)

aws-exports.js

const awsmobile = {
    "aws_project_region": "eu-west-1",
    "aws_cognito_identity_pool_id": "xxxxx",
    "aws_cognito_region": "eu-west-1",
    "aws_user_pools_id": "eu-west-1_B0DDvRpxx",
    "aws_user_pools_web_client_id": "xxxxx",
    "oauth": {
        "domain": "[xxxxxxxxx/)",
        "scope": [
            "phone",
            "email",
            "openid",
            "profile",
            "aws.cognito.signin.user.admin"
        ],
        "redirectSignIn": "Villeo://",
        "redirectSignOut": "Villeo://",
        "responseType": "code"
    },
    "federationTarget": "COGNITO_USER_POOLS",
    "aws_cognito_username_attributes": [
        "EMAIL"
    ],
    "aws_cognito_social_providers": [
        "FACEBOOK",
        "GOOGLE",
        "APPLE"
    ],
    "aws_cognito_signup_attributes": [
        "EMAIL"
    ],
    "aws_cognito_mfa_configuration": "OFF",
    "aws_cognito_mfa_types": [
        "SMS"
    ],
    "aws_cognito_password_protection_settings": {
        "passwordPolicyMinLength": 8,
        "passwordPolicyCharacters": []
    },
    "aws_cognito_verification_mechanisms": [
        "EMAIL"
    ],
    "aws_appsync_graphqlEndpoint": xxxxxxx/graphql",
    "aws_appsync_region": "eu-west-1",
    "aws_appsync_authenticationType": "AMAZON_COGNITO_USER_POOLS",
    "aws_cloud_logic_custom": [
        {
            "name": "Pinpoint",
            "endpoint": "xxxxx/prod",
            "region": "eu-west-1"
        },
        {
            "name": "AdminQueries",
            "endpoint": xxxxx/prod",
            "region": "eu-west-1"
        }
    ],
    "aws_user_files_s3_bucket": "xxxx-prod",
    "aws_user_files_s3_bucket_region": "eu-west-1",
    "aws_mobile_analytics_app_id": "xxxxx",
    "aws_mobile_analytics_app_region": "eu-west-1"
};

Manual configuration

No response

Additional configuration

No response

Mobile Device

From google play console :

Huawei HUAWEI P smart 2020 Huawei P20 Huawei Y9 Prime 2019 Samsung Galaxy Note3 (Keep in mind that other users may have not shared crash infos)

Mobile Operating System

Android 5.0, 9 & 10 (Keep in mind that other users may have not shared crash infos)

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 16 (5 by maintainers)

Most upvoted comments

The patch works fine for me. Thanks @ChrisLFieldsII. Here is the Java implementation:

package com.myapp;
/**PATCH*/
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import android.content.Intent;
import android.os.Bundle;
import com.amazonaws.amplify.pushnotification.modules.RNPushNotificationJsDelivery;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;

public class MainActivity extends ReactActivity {

  /**
   * Returns the name of the main component registered from JavaScript. This is used to schedule
   * rendering of the component.
   */
  @Override
  protected String getMainComponentName() {
    return "MyApp";
  }

  /**
   * Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
   * you can specify the renderer you wish to use - the new renderer (Fabric) or the old renderer
   * (Paper).
   */
  @Override
  protected ReactActivityDelegate createReactActivityDelegate() {
    return new MainActivityDelegate(this, getMainComponentName());
  }

  public static class MainActivityDelegate extends ReactActivityDelegate {
    public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
      super(activity, mainComponentName);
    }

    @Override
    protected ReactRootView createRootView() {
      ReactRootView reactRootView = new ReactRootView(getContext());
      // If you opted-in for the New Architecture, we enable the Fabric Renderer.
      reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
      return reactRootView;
    }

    @Override
    protected boolean isConcurrentRootEnabled() {
      // If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18).
      // More on this on https://reactjs.org/blog/2022/03/29/react-v18.html
      return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
    }
  }

  /**
   * React navigation - https://reactnavigation.org/docs/getting-started/
   */
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(null);
    // handles cold starts
    handleNotificationOnIntent(getIntent());
  }

  @Override
  public void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    setIntent(intent);

    // handles warm starts
    handleNotificationOnIntent(intent);
  }

  private void handleNotificationOnIntent(Intent intent) {
    if (intent == null) {
      return;
    }
    Bundle notification = intent.getBundleExtra("notification");
    if (notification != null) {
      // send the message to device emitter
      // Construct and load our normal React JS code bundle
      ReactApplication applicationContext = (ReactApplication) getApplicationContext();
      ReactInstanceManager mReactInstanceManager = applicationContext.getReactNativeHost().getReactInstanceManager();
      ReactContext reactContext = mReactInstanceManager.getCurrentReactContext();
      if (reactContext != null) {
        RNPushNotificationJsDelivery jsDelivery =
                new RNPushNotificationJsDelivery((ReactApplicationContext)reactContext);
        jsDelivery.emitNotificationOpened(notification);
      }
    }
  }
}

@ChrisLFieldsII Hello!

Would you please advise on you patch. I’m trying to implement it in my app in order to get PN work on Android 12+. So my question is about this patch in onCreate method:

        // handles cold starts
        handleNotificationOnIntent(intent)

We passing the intent as an argument but there is no intent in scope. How does it suppose to work?

Thanks in advance!

Hmm sounds like maybe your MainActivity is java?

It’s this api though: https://developer.android.com/reference/android/app/Activity#getIntent()

So if you are using java, you might need to change intent to getIntent()

thats the first thought that comes to my mind, just a difference between kotlin and java syntax as my example is kotlin

Here is the patch I am using to make the push notifications module compatible with android 12

Note that the changes in the RNPushNotificationBroadcastReceiver.java are useless. Its the changes in RNPushNotificationHelper.java that matter.

diff --git a/node_modules/@aws-amplify/pushnotification/android/src/main/java/com/amazonaws/amplify/pushnotification/RNPushNotificationMessagingService.java b/node_modules/@aws-amplify/pushnotification/android/src/main/java/com/amazonaws/amplify/pushnotification/RNPushNotificationMessagingService.java
index 1057d67..7fdc8e9 100644
--- a/node_modules/@aws-amplify/pushnotification/android/src/main/java/com/amazonaws/amplify/pushnotification/RNPushNotificationMessagingService.java
+++ b/node_modules/@aws-amplify/pushnotification/android/src/main/java/com/amazonaws/amplify/pushnotification/RNPushNotificationMessagingService.java
@@ -104,12 +104,10 @@ public class RNPushNotificationMessagingService extends FirebaseMessagingService
 
         Log.i(LOG_TAG, "sendNotification: " + bundle);
 
-        if (!isForeground) {
-            Application applicationContext = (Application) context.getApplicationContext();
-            RNPushNotificationHelper pushNotificationHelper = new RNPushNotificationHelper(applicationContext);
-            pushNotificationHelper.sendToNotificationCentre(bundle);
-        }
-
+        // we want to send notification to center api regardless of if app in fg/bg
+        Application applicationContext = (Application) context.getApplicationContext();
+        RNPushNotificationHelper pushNotificationHelper = new RNPushNotificationHelper(applicationContext);
+        pushNotificationHelper.sendToNotificationCentre(bundle);
     }
 
     // whether the app is in foreground
diff --git a/node_modules/@aws-amplify/pushnotification/android/src/main/java/com/amazonaws/amplify/pushnotification/modules/RNPushNotificationBroadcastReceiver.java b/node_modules/@aws-amplify/pushnotification/android/src/main/java/com/amazonaws/amplify/pushnotification/modules/RNPushNotificationBroadcastReceiver.java
index 3f0a87f..041c140 100644
--- a/node_modules/@aws-amplify/pushnotification/android/src/main/java/com/amazonaws/amplify/pushnotification/modules/RNPushNotificationBroadcastReceiver.java
+++ b/node_modules/@aws-amplify/pushnotification/android/src/main/java/com/amazonaws/amplify/pushnotification/modules/RNPushNotificationBroadcastReceiver.java
@@ -15,6 +15,8 @@ package com.amazonaws.amplify.pushnotification.modules;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
 import android.util.Log;
 
 import com.facebook.react.ReactApplication;
@@ -24,6 +26,9 @@ import com.facebook.react.bridge.ReactContext;
 
 /**
  * The Amazon Pinpoint push notification receiver.
+ *
+ * NOTE: this is no longer used due to android 12 req: 
+ * https://developer.android.com/about/versions/12/behavior-changes-12#notification-trampoline-update-app
  */
 public class RNPushNotificationBroadcastReceiver extends BroadcastReceiver {
 
@@ -33,6 +38,8 @@ public class RNPushNotificationBroadcastReceiver extends BroadcastReceiver {
         String packageName = context.getPackageName();
         Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
         String className = launchIntent.getComponent().getClassName();
+        Log.d(LOG_TAG, String.format("%s %s", packageName, className));
+
         try {
             return Class.forName(className);
         } catch (ClassNotFoundException e) {
@@ -41,9 +48,15 @@ public class RNPushNotificationBroadcastReceiver extends BroadcastReceiver {
         }
     }
 
-    private void openApp(Context context) {
+    private void openApp(Context context, Bundle notification) {
         Class intentClass = getMainActivityClass(context);
-        Intent launchIntent = new Intent(context, intentClass);
+        String deeplink = notification.getString("pinpoint.deeplink");
+        Boolean hasDeeplink = deeplink != null;
+
+        // if pinpoint data has a deeplink, we use an ACTION_VIEW intent (https://developer.android.com/reference/android/content/Intent#ACTION_VIEW)
+        // using this type of Intent is what native android Linking.getInitialUrl expects (https://github.com/facebook/react-native/blob/v0.64.3/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java#L59)
+        // this allows us to handle deep linking on cold push
+        Intent launchIntent = hasDeeplink ? new Intent(Intent.ACTION_VIEW, Uri.parse(deeplink)) : new Intent(context, intentClass);
         if (launchIntent == null) {
             Log.e(LOG_TAG, "Couldn't get app launch intent for campaign notification.");
             return;
@@ -51,6 +64,7 @@ public class RNPushNotificationBroadcastReceiver extends BroadcastReceiver {
 
         launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
         launchIntent.setPackage(null);
+        Log.e(LOG_TAG, "opening app");
         context.startActivity(launchIntent);
     }
 
@@ -77,7 +91,7 @@ public class RNPushNotificationBroadcastReceiver extends BroadcastReceiver {
                 mReactInstanceManager.createReactContextInBackground();
             }
         }
-        openApp(context);
+        openApp(context, intent.getBundleExtra("notification"));
     }
 
     private void emitNotificationOpenedEvent(ReactContext reactContext, Intent intent){
diff --git a/node_modules/@aws-amplify/pushnotification/android/src/main/java/com/amazonaws/amplify/pushnotification/modules/RNPushNotificationHelper.java b/node_modules/@aws-amplify/pushnotification/android/src/main/java/com/amazonaws/amplify/pushnotification/modules/RNPushNotificationHelper.java
index 8f3f97f..dc6d361 100644
--- a/node_modules/@aws-amplify/pushnotification/android/src/main/java/com/amazonaws/amplify/pushnotification/modules/RNPushNotificationHelper.java
+++ b/node_modules/@aws-amplify/pushnotification/android/src/main/java/com/amazonaws/amplify/pushnotification/modules/RNPushNotificationHelper.java
@@ -78,7 +78,7 @@ public class RNPushNotificationHelper {
         notificationIntent.putExtra(RNPushNotificationPublisher.NOTIFICATION_ID, notificationID);
         notificationIntent.putExtras(bundle);
 
-        return PendingIntent.getBroadcast(context, notificationID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+        return PendingIntent.getBroadcast(context, notificationID, notificationIntent, PendingIntent.FLAG_IMMUTABLE);
     }
 
     public void sendNotificationScheduled(Bundle bundle) {
@@ -221,7 +221,8 @@ public class RNPushNotificationHelper {
             if (smallIcon != null) {
                 smallIconResId = res.getIdentifier(smallIcon, "mipmap", packageName);
             } else {
-                smallIconResId = res.getIdentifier("ic_notification", "mipmap", packageName);
+                // our default notification icon is in drawable dir
+                smallIconResId = res.getIdentifier("ic_notification", "drawable", packageName);
             }
 
             if (smallIconResId == 0) {
@@ -245,6 +246,7 @@ public class RNPushNotificationHelper {
             }
 
             notification.setSmallIcon(smallIconResId);
+            notification.setColor(Color.BLACK); // change notification icon color to black
             String bigText = bundle.getString("bigText");
 
             if (bigText == null) {
@@ -254,8 +256,21 @@ public class RNPushNotificationHelper {
 
             notification.setStyle(new NotificationCompat.BigTextStyle().bigText(bigText));
 
-            Intent intent = new Intent(context, RNPushNotificationBroadcastReceiver.class);
+            String deeplink = bundle.getString("pinpoint.deeplink");
+            Boolean hasDeeplink = deeplink != null;
+            // if pinpoint data has a deeplink, we use an ACTION_VIEW intent (https://developer.android.com/reference/android/content/Intent#ACTION_VIEW)
+            // using this type of Intent is what native android Linking.getInitialUrl expects (https://github.com/facebook/react-native/blob/v0.64.3/ReactAndroid/src/main/java/com/facebook/react/modules/intent/IntentModule.java#L59)
+            // this allows us to handle deep linking on cold push
+            Intent intent = hasDeeplink ? new Intent(Intent.ACTION_VIEW, Uri.parse(deeplink)) : context.getPackageManager().getLaunchIntentForPackage(packageName);
             intent.putExtra("notification", bundle);
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+            int notificationID = Integer.parseInt(notificationIdString);
+
+            PendingIntent pendingIntent = PendingIntent.getActivity(context, notificationID, intent,
+                    PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
+
+            notification.setContentIntent(pendingIntent);
 
             Log.i(LOG_TAG, "sendNotification: " + intent);
 
@@ -311,15 +326,6 @@ public class RNPushNotificationHelper {
                 }
             }
 
-            int notificationID = Integer.parseInt(notificationIdString);
-
-            // PendingIntent pendingIntent = PendingIntent.getActivity(context, notificationID, intent,
-            //         PendingIntent.FLAG_UPDATE_CURRENT);
-            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, notificationID, intent,
-                        PendingIntent.FLAG_UPDATE_CURRENT);
-
-            notification.setContentIntent(pendingIntent);
-
             if (!bundle.containsKey("vibrate") || bundle.getBoolean("vibrate")) {
                 long vibration = bundle.containsKey("vibration") ? (long) bundle.getDouble("vibration") : DEFAULT_VIBRATION;
                 if (vibration == 0)
@@ -354,7 +360,7 @@ public class RNPushNotificationHelper {
                     bundle.putString("action", action);
                     actionIntent.putExtra("notification", bundle);
                     PendingIntent pendingActionIntent = PendingIntent.getBroadcast(context, notificationID, actionIntent,
-                            PendingIntent.FLAG_UPDATE_CURRENT);
+                            PendingIntent.FLAG_IMMUTABLE);
                     notification.addAction(icon, action, pendingActionIntent);
                 }
             }

I totally forgot to add this… After patching the amplify pushnotification module, I had to then modify my MainActivity to handle the PendingIntent attached to the notification via notification.setContentIntent(pendingIntent);

Here is what that looks like

package com.your.package
import android.content.Intent
import expo.modules.ReactActivityDelegateWrapper
import android.os.Bundle
import android.util.Log
import com.amazonaws.amplify.pushnotification.modules.RNPushNotificationJsDelivery
import com.facebook.react.*
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContext
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView

class MainActivity : ReactActivity() {
    companion object {
        val LOG_TAG = "com.your.package"
    }

    override fun getMainComponentName() = "package"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        Log.d(LOG_TAG, "onCreate")

        // handles cold starts
        handleNotificationOnIntent(intent)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)

        this.intent = intent

        Log.d(LOG_TAG, "onNewIntent")

        // handles warm starts
        handleNotificationOnIntent(intent)
    }

    private fun handleNotificationOnIntent(intent: Intent?) {
        val notification = intent?.getBundleExtra("notification")
        if (notification != null) {
            // send the message to device emitter
            // Construct and load our normal React JS code bundle
            val mReactInstanceManager =
                (this.applicationContext as ReactApplication).reactNativeHost.reactInstanceManager
            val reactContext = mReactInstanceManager.currentReactContext
            if (reactContext != null) {
                Log.d(LOG_TAG, "emitting notification opened event")

                val jsDelivery =
                    RNPushNotificationJsDelivery(reactContext as ReactApplicationContext?)
                jsDelivery.emitNotificationOpened(notification)
            } else {
                Log.e(LOG_TAG, "failed to emit notification opened event due to no react context")
            }
        }
    }
}

The key is onCreate and onNewIntent to check if a notification is attached to the intent bundle and if so call handleNotificationOnIntent which was just ripped from what AWS already wrote.