urbanairship / react-native-airship

Airship React Native module
Other
88 stars 62 forks source link

Crash when tapping notification if app uses both Airship and @react-native-firebase/messaging #605

Open 4l3ss opened 19 hours ago

4l3ss commented 19 hours ago

Preliminary Info

What Airship dependencies are you using?

@ua/react-native-airship 20.0.0

What are the versions of any relevant development tools you are using?

react-native 0.74.6

@react-native-firebase/analytics 21.3.0
@react-native-firebase/app 21.3.0
@react-native-firebase/messaging 21.3.0

Report

What unexpected behavior are you seeing?

When the app receives an airship notification, the app crashes with the following exception:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[GUL_AppDelegate-D04A089E-53DD-4FE5-A530-72013F0041AE userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:]: unrecognized selector sent to instance 0x303bed4c0'

The problem disappears when removing the firebase messaging SDK, or when downgrading @ua/react-native-airship to 19.3.2

I understand the fix might not be on Airship side, but I'm filling an issue here for now because the wrong behavior appeared after upgrading the Airship SDK. Maybe it's a known issue ?

What is the expected behavior?

When tapping on a notification, the app should open without crashing.

What are the steps to reproduce the unexpected behavior?

It's a bit hard to setup from scratch. It seems it comes from incompatibilities between @react-native-firebase/messaging and @ua/react-native-airship.

Do you have logging for the issue?

When I receive the push and then tap on it :

[I] AirshipKit/DefaultAppIntegrationDelegate.swift processPush(_:isForeground:presentationOptions:completionHandler:) [Line 201] Application received remote notification: [AnyHashable("com.urbanairship.metadata"): eyJ2ZXJzaW9uX2lkIjoxLCJ0aW1lIjoxNzMwNzQ4MTE3MjQ1LCJwdXNoX2lkIjoiMGVhNjIyYjAtOWFlMi0xMWVmLWFiYTgtMDAwMDBhMWFjZWNmIiwicmV0YXJnZXRpbmciOmZhbHNlLCJjb250ZXh0Ijp7fX0=, AnyHashable("aps"): {
    alert = Test;
}, AnyHashable("_"): f2e873d2-8b3d-4fd7-80ee-54276f4f2e22, AnyHashable("^d"): https://www-qa.*****]
[D] AirshipKit/ActionRunner.swift run(actionName:arguments:) [Line 53] Action ^d predicate rejected argument: ActionArguments(value: AirshipKit.AirshipJSON.string("https://www-qa.*****"), situation: AirshipKit.ActionSituation, metadata: ["com.urbanairship.is_foreground_presentation": true, "com.urbanairship.payload": AirshipKit.AirshipJSON.object(["aps": AirshipKit.AirshipJSON.object(["alert": AirshipKit.AirshipJSON.string("Test")]), "^d": AirshipKit.AirshipJSON.string("https://www-qa.*****"), "com.urbanairship.metadata": AirshipKit.AirshipJSON.string("eyJ2ZXJzaW9uX2lkIjoxLCJ0aW1lIjoxNzMwNzQ4MTE3MjQ1LCJwdXNoX2lkIjoiMGVhNjIyYjAtOWFlMi0xMWVmLWFiYTgtMDAwMDBhMWFjZWNmIiwicmV0YXJnZXRpbmciOmZhbHNlLCJjb250ZXh0Ijp7fX0="), "_": AirshipKit.AirshipJSON.string("f2e873d2-8b3d-4fd7-80ee-54276f4f2e22")])]).
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[GUL_AppDelegate-D04A089E-53DD-4FE5-A530-72013F0041AE userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:]: unrecognized selector sent to instance 0x303bed4c0'
*** First throw call stack:
(0x1980807cc 0x1953532e4 0x1981868c8 0x19b93e058 0x19801e8b4 0x19801e430 0x10c511e24 0x10b5725b8 0x10c38f5ec 0x10c38dcfc 0x19ac6bd9c 0x19a9fa0e8 0x19aab9824 0x19aab9404 0x1b16401bc 0x1b163fd6c 0x1b160f3c8 0x1b161ddb8 0x1b161dc44 0x1b1622114 0x10196271c 0x10196613c 0x1b161f300 0x1b161f280 0x1b161f158 0x198054328 0x1980542bc 0x198051dc0 0x198050fbc 0x198050830 0x1e40301c4 0x19abb6eb0 0x19ac655b4 0x10b070ef8 0x1bda3eec8)
libc++abi: terminating due to uncaught exception of type NSException
rlepinski commented 16 hours ago

Thanks for the report, I'll see if I can reproduce and figure out the core issue here

rlepinski commented 15 hours ago

Ok, was able to reproduce. Not really sure the fix yet but this is the order of things happening:

App starts:

Delegate method:

I am guessing we made a change and the order of swizzling changed. If firebase swizzled first I don't think we would have this issue.

rlepinski commented 14 hours ago

Ok, some more findings:

We are unswizzling methods from the delegate when it changes, but there is no way to remove a method from a class, just add and replace. Since our empty delegate has no methods, it keeps the original swizzled method and causes the looping.

I believe we can address this on our end without a firebase change if we check to make sure the message receiver is the current notification delegate. If they do not match, and airship is called, it means the original did not have a method so we can no-op and break the cycle.

This is going to require a native SDK change which Ill try to get a patch together tomorrow. Once that is out then it takes a few more hours to get a react patch out.