CleverTap / clevertap-android-sdk

CleverTap Android SDK

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Crash][Push Primer]Crash in Android 13 when prompting push push primer

naveenchandan opened this issue · comments

Describe the bug
Crash with push primer reported in Firebase

To Reproduce
Steps to reproduce the behavior:

  1. Happening when prompting push primer.
  2. cleverTapAPI.promptPushPrimer(jsonObject);

Expected behavior
App should not crash when prompting push primer.

Screenshots/Logs

       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3645)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3782)
       at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
       at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:201)
       at android.os.Looper.loop(Looper.java:288)
       at android.app.ActivityThread.main(ActivityThread.java:7872)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

Caused by java.lang.NullPointerException:
       at java.util.Objects.requireNonNull(Objects.java:220)
       at com.clevertap.android.sdk.inapp.InAppController.promptPushPrimer(InAppController.java:204)
       at com.clevertap.android.sdk.CleverTapAPI.promptPushPrimer(CleverTapAPI.java:1059)
       at com.rapido.passenger.utilies.thridpartysdks.clevertap.CleverTapSdkController.pushPermission(CleverTapSdkController.java:232)
       at com.rapido.passenger.activities.OrderActivity.onCreate(OrderActivity.java:412)
       at android.app.Activity.performCreate(Activity.java:8305)
       at android.app.Activity.performCreate(Activity.java:8284)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1417)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3626)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3782)
       at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
       at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:201)
       at android.os.Looper.loop(Looper.java:288)
       at android.app.ActivityThread.main(ActivityThread.java:7872)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936) 

Environment (please complete the following information):

  • Device: In all devices
  • OS: Android 13
  • CleverTap SDK Version - 4.7.4
  • Android Studio Version - Android Studio Electric Eel | 2022.1.1

Additional context
Crash is happening when we prompting push primer dialog in Android 13, seems like crash is happening inside the class InAppController,
boolean shouldShowRequestPermissionRationale = ActivityCompat.shouldShowRequestPermissionRationale(
Objects.requireNonNull(CoreMetaData.getCurrentActivity()),
ANDROID_PERMISSION_STRING);

Hey @naveenchandan, Can you confirm are you calling ActivityLifecycleCallback.register(this) in you custom application class.

RCA - CoreMetaData.getCurrentActivity() this line is causing the issue here. CleverTap gets the current activity when CleverTap SDK is initialised via either two ways

  1. Registering your application in manifest using com.clevertap.android.sdk.Application
  2. Or if you are using a custom application class then call ActivityLifecycleCallback.register(this), before super.onCreate()

More info regarding initialising CleverTap SDK can be found here

Hey @william-ct ,Thanks for you reply... And yes we are calling ActivityLifecycleCallback.register(this) in our Application Class

Hey @PiyushSinha-PS @naveenchandan

Thanks for you reply... And yes we are calling ActivityLifecycleCallback.register(this) in our Application Class

Ok. Thanks

One more thing, can you move cleverTapDefaultInstance.promptPushPrimer(builder) method inside onResume() of your OrderActivity.java class instead of onCreate() and check?

Hey, we can't try/check from our side, the issue is happening in the production and we are not able to reproduce it on Dev environment

@PiyushSinha-PS Can you confirm in your code where have you called cleverTapDefaultInstance.promptPushPrimer(builder)?

In OrderActivity onCreate..

@PiyushSinha-PS You will have to call cleverTapDefaultInstance.promptPushPrimer(builder) inside onResume() in OrderActivity.java in your next release to fix the crash

Sure we are sending the hotfix and we are doing this change in hotfix.I will keep you update

@william-ct we are facing the same crash in different place. Please check this on priority.

Fatal Exception: java.lang.NullPointerException:
       at java.util.Objects.requireNonNull(Objects.java:220)
       at com.clevertap.android.sdk.PushPermissionManager.requestPermission(PushPermissionManager.java:63)
       at com.clevertap.android.sdk.PushPermissionManager.showHardPermissionPrompt(PushPermissionManager.java:51)
       at com.clevertap.android.sdk.InAppNotificationActivity.showHardPermissionPrompt(InAppNotificationActivity.java:208)
       at com.clevertap.android.sdk.InAppNotificationActivity$1.onClick(InAppNotificationActivity.java:347)
       at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:274)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:223)
       at android.os.Looper.loop(Looper.java:324)
       at android.app.ActivityThread.main(ActivityThread.java:8382)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:582)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1059)

@naveenchandan Did you move cleverTapDefaultInstance.promptPushPrimer(builder) or showHardPermissionPrompt inside onResume() instead of onCreate() in your app and still it crashed with the above exception?

How it will fix this crash by moving to onResume?, how can activity be null if we are calling promptPushPrimer() from onCreate()

@naveenchandan Can you let us know whether this crash is also happening when you moved the methods inside onResume()? If it's a bug we need to understand the root cause hence checking with you

@william-ct will try this in our next app release and will update the status here after release.

@naveenchandan Can you test it in your development build of your app and confirm whether it crashes with the same exception before releasing it in production?

@william-ct We are facing the same on React Native prod app, Can you please help us out here as well?

@Shanie1331 Can you explain in detail which push primer API are you using and also share the entire stack trace of the crash?

@william-ct This happened when the application is not running at all and the user gets a notification. Clevertap is throwing this exception on background task and android 13 (where apiLevel is 33) reporting it as a crash on our logs.

We are using "clevertap-react-native": "1.0.0" npm package

Here is the stack trace

        at java.util.Objects.requireNonNull(Objects.java:220)
        at com.clevertap.android.sdk.inapp.u.B(InAppController.java:28)
        at com.clevertap.android.sdk.inapp.u.A(InAppController.java:22)
        at com.clevertap.android.sdk.h.J0(CleverTapAPI.java:17)
        at com.clevertap.react.CleverTapModule.promptForPushPermission(CleverTapModule.java:7)
        at java.lang.reflect.Method.invoke(Method.java:-2)
        at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:149)
        at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:148)
        at com.facebook.react.bridge.queue.NativeRunnable.run(NativeRunnable.java:-2)
        at android.os.Handler.handleCallback(Handler.java:942)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:1)
        at android.os.Looper.loopOnce(Looper.java:226)
        at android.os.Looper.loop(Looper.java:313)
        at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:38)
        at java.lang.Thread.run(Thread.java:1012)```

@Shanie1331 Can you explain in more detail how did you integrate the push primer in your app and from where you called CleverTapModule.promptForPushPermission?

This happened when the application is not running at all and the user gets a notification.

Can you explain the use case as to how did you integrate the above pushPermission() flow?

@william-ct Use case: get notification permission for android>=13

Clevertap.promptForPushPermission(false) called this globally.

@william-ct Can you suggest any documentation from clevertap how and where to integrate promptForPushPermission

@satishbonam You can use the Clevertap.promptForPushPermission(false) globally, but do ensure to call it only after onCreate() . You can find more on this link for integrating runtime notifications using CleverTap.

@william-ct we are using the react-native for clevertap. Ideally above native code changes should be handled in the same package right? We don't want to do any native changes to handle specific use-case. Please let us know how we need to proceed.

@william-ct any update or progress on this issue?

@satishbonam The crash is occurring because we require an activity instance of the app in order to show the push permission dialog. To obtain this instance, we use ActivityLifecycleCallback.register(this) to register the activity instance with the callback. I assume you have already done this.

The ActivityLifecycleCallback provides several callbacks for activity lifecycle, but we use public void onActivityResumed(Activity activity) to obtain the running activity instance and show the dialog on that instance.

To use this approach in your React Native component or Android activity, you should call Clevertap.promptForPushPermission(false) after the component or activity is rendered. This way, we can capture a non-null activity instance and show the dialog.

In React Native, the equivalent of onActivityResumed is componentDidUpdate(), so you should call the Clevertap.promptForPushPermission(false) method inside this method.

@PiyushSinha-PS Thankyou for detailed explanation. Please update react-native cleveratap documentation accordingly.

This is happening in react native sdk as well

Fatal Exception: java.lang.NullPointerException:
at java.util.Objects.requireNonNull(Objects.java:220)
at com.clevertap.android.sdk.inapp.InAppController.promptPushPrimer(InAppController.java:204)
at com.clevertap.android.sdk.inapp.InAppController.promptPermission(InAppController.java:232)
at com.clevertap.android.sdk.CleverTapAPI.promptForPushPermission(CleverTapAPI.java:1072)
at com.clevertap.react.CleverTapModule.promptForPushPermission(CleverTapModule.java:309)
at java.lang.reflect.Method.invoke(Method.java)
at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:372)
at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:188)
at com.facebook.jni.NativeRunnable.run(NativeRunnable.java)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:228)
at java.lang.Thread.run(Thread.java:1012)

Hi @AnkitM-Liv

Please answer the following questions:

  1. Which push primer API are you using?
  2. Is the crash reproducible?
  3. In which component's lifecycle method is it positioned?
  4. At which point(s) this API gets called?

We are using clevertap-react-native : 1.0.2
When are you going to provide this fix in react native sdk ?