diff --git a/native/android/app/src/main/java/app/comm/android/notifications/CommAndroidNotificationsEventEmitter.java b/native/android/app/src/main/java/app/comm/android/notifications/CommAndroidNotificationsEventEmitter.java --- a/native/android/app/src/main/java/app/comm/android/notifications/CommAndroidNotificationsEventEmitter.java +++ b/native/android/app/src/main/java/app/comm/android/notifications/CommAndroidNotificationsEventEmitter.java @@ -1,10 +1,13 @@ package app.comm.android.notifications; +import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.util.Log; import androidx.localbroadcastmanager.content.LocalBroadcastManager; +import com.facebook.react.bridge.ActivityEventListener; import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContext; @@ -21,6 +24,8 @@ CommAndroidNotificationsEventEmitter(ReactApplicationContext reactContext) { super(reactContext); + reactContext.addActivityEventListener( + new CommAndroidNotificationsActivityEventListener()); LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(reactContext); localBroadcastManager.registerReceiver( @@ -39,6 +44,12 @@ @ReactMethod public void addListener(String eventName) { this.listenersCount += 1; + + // This is for the edge case that the app was started by tapping + // on notification in notification center. We want to open the app + // and navigate to relevant thread. We need to parse notification + // so that JS can get its threadID. + sendInitialNotificationFromIntentToJS(getCurrentActivity().getIntent()); } @ReactMethod @@ -55,6 +66,20 @@ .emit(eventName, body); } + private void sendInitialNotificationFromIntentToJS(Intent intent) { + RemoteMessage initialNotification = intent.getParcelableExtra("message"); + if (initialNotification == null) { + return; + } + WritableMap jsReadableNotification = + CommAndroidNotificationParser.parseRemoteMessageToJSForegroundMessage( + initialNotification); + if (jsReadableNotification != null) { + sendEventToJS( + "commAndroidNotificationsNotificationOpened", jsReadableNotification); + } + } + private class CommAndroidNotificationsTokenReceiver extends BroadcastReceiver { @Override @@ -78,4 +103,21 @@ } } } + + private class CommAndroidNotificationsActivityEventListener + implements ActivityEventListener { + @Override + public void onNewIntent(Intent intent) { + sendInitialNotificationFromIntentToJS(intent); + } + + @Override + public void onActivityResult( + Activity activity, + int requestCode, + int resultCode, + Intent data) { + // Required by ActivityEventListener, but not needed for this project + } + } } diff --git a/native/push/android.js b/native/push/android.js --- a/native/push/android.js +++ b/native/push/android.js @@ -45,6 +45,7 @@ function getCommAndroidNotificationsEventEmitter(): NativeEventEmitter<{ commAndroidNotificationsToken: [string], commAndroidNotificationsForegroundMessage: [AndroidForegroundMessage], + commAndroidNotificationsNotificationOpened: [AndroidForegroundMessage], }> { return new NativeEventEmitter(CommAndroidNotificationsEventEmitter); } diff --git a/native/push/push-handler.react.js b/native/push/push-handler.react.js --- a/native/push/push-handler.react.js +++ b/native/push/push-handler.react.js @@ -3,7 +3,6 @@ import * as Haptics from 'expo-haptics'; import * as React from 'react'; import { Platform, Alert, LogBox } from 'react-native'; -import type { NotificationOpen } from 'react-native-firebase'; import { Notification as InAppNotification } from 'react-native-in-app-message'; import NotificationsIOS from 'react-native-notifications'; import { useDispatch } from 'react-redux'; @@ -109,7 +108,6 @@ currentState: ?string = getCurrentLifecycleState(); appStarted = 0; androidNotificationsEventSubscriptions: Array = []; - androidNotifOpenListener: ?() => void = null; initialAndroidNotifHandled = false; openThreadOnceReceived: Set = new Set(); lifecycleSubscription: ?EventSubscription; @@ -155,11 +153,11 @@ 'commAndroidNotificationsForegroundMessage', this.androidMessageReceived, ), + commAndroidNotificationsEventEmitter.addListener( + 'commAndroidNotificationsNotificationOpened', + this.androidNotificationOpened, + ), ); - - this.androidNotifOpenListener = firebase - .notifications() - .onNotificationOpened(this.androidNotificationOpened); } if (this.props.connection.status === 'connected') { @@ -194,10 +192,6 @@ androidNotificationsEventSubscription.remove(); } this.androidNotificationsEventSubscriptions = []; - if (this.androidNotifOpenListener) { - this.androidNotifOpenListener(); - this.androidNotifOpenListener = null; - } } } @@ -537,9 +531,11 @@ }); } - androidNotificationOpened = async (notificationOpen: NotificationOpen) => { + androidNotificationOpened = async ( + notificationOpen: AndroidForegroundMessage, + ) => { this.onPushNotifBootsApp(); - const { threadID } = notificationOpen.notification.data; + const { threadID } = notificationOpen; this.onPressNotificationForThread(threadID, true); };