[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:
- Happening when prompting push primer.
- 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
- Registering your application in manifest using
com.clevertap.android.sdk.Application
- Or if you are using a custom application class then call
ActivityLifecycleCallback.register(this)
, beforesuper.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:
- Which push primer API are you using?
- Is the crash reproducible?
- In which component's lifecycle method is it positioned?
- 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 ?