customerio / customerio-android

This is the official Customer.io SDK for Android.
MIT License
13 stars 9 forks source link

UninitializedPropertyAccessException - lateinit property siteId has not been initialized #370

Closed remi-ollivier closed 4 months ago

remi-ollivier commented 4 months ago

SDK version: 3.10.0

Environment: Production

Are logs available?

Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{ng.com.fairmoney.fairmoney/io.customer.messaginginapp.gist.presentation.GistModalActivity}: kotlin.UninitializedPropertyAccessException: lateinit property siteId has not been initialized
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3013)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3148)
       at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
       at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1861)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:193)
       at android.app.ActivityThread.main(ActivityThread.java:6819)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:497)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:912)

Describe the bug App crashes when GistModalActivity is initiated

To Reproduce Happens on production and can not reproduce locally

Expected behavior No crash

Screenshots

Additional context

Happens after we updated the SDK from 3.8.1 to 3.10.0

Shahroz16 commented 4 months ago

Hey @remi-ollivier thank you for reaching out, can you please share how you are initializing the SDK? and is there a way to bypass that initialization due to any conditioning in your app?

The error mentions the field siteId is uninitialized while it gets initialized when you initialize the SDK along with in-app module in the Application class. So it should be the first thing that gets initialized.

remi-ollivier commented 4 months ago

Sure! We have a CustomerIOInitializer which works like this

private val customerIO: Deferred<CustomerIO?> =
        GlobalScope.async(Dispatchers.IO, start = CoroutineStart.LAZY) {
                CustomerIO.Builder(
                    siteId = BuildKonfig.CUSTOMER_IO_SITE_ID,
                    apiKey = BuildKonfig.CUSTOMER_IO_API_KEY,
                    appContext = application,
                )
                    .addCustomerIOModule(
                        ModuleMessagingPushFCM(
                            config = MessagingPushModuleConfig.Builder().apply {
                                setNotificationCallback(this@CustomerIOInitializer)
                                setRedirectDeepLinksToOtherApps(false)
                            }.build()
                        )
                    )
                    .addCustomerIOModule(ModuleMessagingInApp())
                    .build()
        }

        override val instance: Deferred<CustomerIO?> = customerIO

and we access it by calling

customerIOInitializer.instance?.await()

We need to access it asynchronously because the initialization time takes time on our main thread and it causes ANRs, so we try to unload the main thread. Please let me know if you need more information

Shahroz16 commented 4 months ago

@remi-ollivier I think late initialization could be the reason because we need to be synchronous. The issue of ANR in your case is also not helpful, but we are discussing this internally how to tackle this. We might make it configurable the first time launching of the in-app to pre-cache the assets which you are reporting as something that causes ANR.

Shahroz16 commented 4 months ago

@remi-ollivier same from before, now you wont have to late initialize because of ANR issue and if you don't late initialize you won't be facing this.

Closing this, feel free to re-open, if you face this again.

remi-ollivier commented 2 months ago

Hi. We're still facing this issue but now the stacktrace is different, I don't know if this can help:

io.customer.messaginginapp.gist.presentation.GistSdk.getSiteId (GistSdk.kt:34)
io.customer.messaginginapp.gist.presentation.GistView.setup (GistView.kt:49)
io.customer.messaginginapp.gist.presentation.GistModalActivity.onCreate (GistModalActivity.kt:64)
android.app.Activity.performCreate (Activity.java:8385)
android.app.Activity.performCreate (Activity.java:8363)
android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1379)
android.app.ActivityThread.performLaunchActivity (ActivityThread.java:3912)
android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:4096)
android.app.servertransaction.LaunchActivityItem.execute (LaunchActivityItem.java:103)
android.app.servertransaction.TransactionExecutor.executeCallbacks (TransactionExecutor.java:135)
android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:95)
android.app.ActivityThread$H.handleMessage (ActivityThread.java:2441)
android.os.Handler.dispatchMessage (Handler.java:106)
android.os.Looper.loopOnce (Looper.java:233)
android.os.Looper.loop (Looper.java:334)
android.app.ActivityThread.main (ActivityThread.java:8399)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:582)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1068)

Version is 3.11.1. We're planning to upgrade to 4.1.0, but will it be enough to solve the issue? Any idea how we can solve this? Thanks

Shahroz16 commented 2 months ago

Hey @remi-ollivier, we are in process of rolling out some major changes to in-app. Appreciate your patience here, you would need to migrate to 4.x after that release. I'll let you know.

remi-ollivier commented 2 months ago

I have already started upgrading the SDK to version 4.1.0 but I faced this crash during initialization:

FATAL EXCEPTION: DefaultDispatcher-worker-3
                 Process: ng.com.fairmoney.fairmoney.debug, PID: 15678
                 kotlin.reflect.jvm.internal.KotlinReflectionInternalError: Unresolved class: class java.lang.String (kind = null)
                    at kotlin.reflect.jvm.internal.KClassImpl.createSyntheticClassOrFail(KClassImpl.kt:339)
                    at kotlin.reflect.jvm.internal.KClassImpl.access$createSyntheticClassOrFail(KClassImpl.kt:49)
                    at kotlin.reflect.jvm.internal.KClassImpl$Data.descriptor_delegate$lambda$0(KClassImpl.kt:67)
                    at kotlin.reflect.jvm.internal.KClassImpl$Data.accessor$KClassImpl$Data$lambda0(Unknown Source:0)
                    at kotlin.reflect.jvm.internal.KClassImpl$Data$$Lambda$0.invoke(Unknown Source:2)
                    at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:70)
                    at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32)
                    at kotlin.reflect.jvm.internal.KClassImpl$Data.getDescriptor(KClassImpl.kt:53)
                    at kotlin.reflect.jvm.internal.KClassImpl.getDescriptor(KClassImpl.kt:193)
                    at kotlin.reflect.jvm.internal.KClassImpl.getDescriptor(KClassImpl.kt:49)
                    at kotlin.reflect.full.KClassifiers.createType(KClassifiers.kt:47)
                    at kotlin.reflect.jvm.internal.CachesKt.CACHE_FOR_BASE_CLASSIFIERS$lambda$2(caches.kt:37)
                    at kotlin.reflect.jvm.internal.CachesKt.accessor$CachesKt$lambda2(Unknown Source:0)
                    at kotlin.reflect.jvm.internal.CachesKt$$Lambda$2.invoke(Unknown Source:2)
                    at kotlin.reflect.jvm.internal.ConcurrentHashMapCache.get(CacheByClass.kt:92)
                    at kotlin.reflect.jvm.internal.CachesKt.getOrCreateKType(caches.kt:55)
                    at kotlin.reflect.jvm.internal.ReflectionFactoryImpl.typeOf(ReflectionFactoryImpl.java:123)
                    at kotlin.jvm.internal.Reflection.typeOf(Reflection.java:128)
                    at io.customer.sdk.DataPipelineInstance.track(DataPipelineInstance.kt:267)
                    at io.customer.sdk.CustomerIO.trackDeviceAttributes(CustomerIO.kt:301)
                    at io.customer.sdk.CustomerIO.trackDeviceAttributes$default(CustomerIO.kt:278)
                    at io.customer.sdk.CustomerIO.registerDeviceToken(CustomerIO.kt:275)
                    at io.customer.sdk.CustomerIO$subscribeToJourneyEvents$3.invoke(CustomerIO.kt:140)
                    at io.customer.sdk.CustomerIO$subscribeToJourneyEvents$3.invoke(CustomerIO.kt:139)
                    at io.customer.sdk.communication.EventBusKt.subscribe$suspendConversion0(EventBus.kt:23)
                    at io.customer.sdk.communication.EventBusKt.access$subscribe$suspendConversion0(EventBus.kt:1)
                    at io.customer.sdk.CustomerIO$subscribeToJourneyEvents$$inlined$subscribe$3.invoke(EventBus.kt:23)
                    at io.customer.sdk.CustomerIO$subscribeToJourneyEvents$$inlined$subscribe$3.invoke(EventBus.kt:23)
                    at io.customer.sdk.communication.EventBusImpl$subscribe$job$1$2.emit(EventBus.kt:56)
                    at io.customer.sdk.communication.EventBusImpl$subscribe$job$1$2.emit(EventBus.kt:55)
                    at io.customer.sdk.communication.EventBusImpl$subscribe$job$1$invokeSuspend$$inlined$mapNotNull$1$2.emit(Emitters.kt:225)
                    at kotlinx.coroutines.flow.SharedFlowImpl.collect$suspendImpl(SharedFlow.kt:397)
                    at kotlinx.coroutines.flow.SharedFlowImpl$collect$1.invokeSuspend(Unknown Source:15)
                    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
                    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:102)
                    at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:589)
                    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:816)
                    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:720)
                    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:707)
                    Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@ff51422, Dispatchers.Default]

I tested as well on version 4.0.0, same result. Are you aware of this one? Do you know how to fix it? It looks like it's related to this snippet:

addCustomerIOModule(ModuleMessagingInApp())

Thanks in advance!

Shahroz16 commented 2 months ago

@remi-ollivier from the stack trace, it's pointing towards traits being forwarded. Are you using Kotlin serializer in your app? Can you let me know a couple of things

remi-ollivier commented 2 months ago
Shahroz16 commented 2 months ago

Thanks @remi-ollivier, I'll check the SDK with the 2.0. 4.2.0 is also out with the latest updates to in-app.

If you remove this snippet, does the error go away?

addCustomerIOModule(
        ModuleMessagingInApp(
                config = MessagingInAppModuleConfig.Builder(
                    siteId = CUSTOMER_IO_SITE_ID,
                    region = Region.US,
                )
        ).build()
)

Also, can share some logs? so we can see what was the state before it crashed during initialization? Make sure to change log level to debug.

remi-ollivier commented 2 months ago

Without this, it does not crash.

Here are the logs (I changed tokens and app ID)

15:03:52.770  D  creating new instance of CustomerIO SDK.
15:03:52.789  D  initializing SDK module DataPipelines...
15:03:52.789  D  CustomerIO SDK initialized with DataPipelines module.
15:03:52.789  I  Migration site id found, migrating data from previous version.
15:03:52.790  D  Analytics starting = false
15:03:52.790  D  initializing SDK module MessagingInApp...
15:03:52.792  D  Fetching settings on pool-25-thread-1
15:03:52.793  D  initializing SDK module MessagingPushFCM...
15:03:52.793  D  getting current FCM device token...
15:03:52.795  I  Is Firebase available on on this device -> true
15:03:52.796  E  CustomerIO instance is already initialized, skipping the initialization.
15:03:52.796  D  initializing SDK module DataPipelines...
15:03:52.796  D  CustomerIO SDK initialized with DataPipelines module.
15:03:52.796  I  Migration site id found, migrating data from previous version.
15:03:52.796  D  initializing SDK module MessagingInApp...
15:03:52.796  D  initializing SDK module MessagingPushFCM...
15:03:52.796  D  getting current FCM device token...
15:03:52.797  I  Is Firebase available on on this device -> true
15:03:53.151  D  Fetched Settings: {"integrations":{"Customer.io Data Pipelines":{"addBundledMetadata":false,"apiHost":"cdp.customer.io/v1","apiKey":"apiKey","protocol":"https"}},"metrics":{"sampleRate":0},"remotePlugins":null}
15:03:53.152  D  Dispatching update settings on pool-24-thread-4
15:03:53.152  D  Customer.io Data Pipelines performing flush
15:03:53.154  D  Analytics starting = false
15:03:53.229  D  Analytics starting = false
15:03:53.230  D  Analytics starting = true
15:03:53.232  D  Starting migration tracking data...
15:03:53.233  D  Migrating existing token and profile...
15:03:53.233  D  Starting migration tracking data...
15:03:53.233  D  Migrating existing token and profile...
15:03:53.235  D  Requesting migration queue to run...
15:03:53.235  D  Running migration queue...
15:03:53.235  D  queue starting to run tasks...
15:03:53.235  D  Requesting migration queue to run...
15:03:53.235  D  Running migration queue...
15:03:53.235  D  queue starting to run tasks...
15:03:53.235  D  queue done running tasks
15:03:53.235  D  Migration completed successfully
15:03:53.235  D  queue done running tasks
15:03:53.235  D  Migration completed successfully
15:03:53.320  D  got current FCM token: token
15:03:53.321  D  got current FCM token: token
15:03:53.322  I  storing and registering device token token for user profile: null
15:03:53.350  I  updating device attributes: {device_os=29, device_model=Android SDK built for arm64, device_manufacturer=Google, app_version=9.72.0+471-LOCAL-Staging-Debug, cio_sdk_version=3.11.1, device_locale=en-US, push_enabled=true}
15:03:53.387  D  Session Event: {"eventType":1,"sessionData":{"sessionId":"9e6dc061da1f44cfb05532d5c29fabad","firstSessionId":"9e6dc061da1f44cfb05532d5c29fabad","sessionIndex":0,"eventTimestampUs":1726059833337000,"dataCollectionStatus":{"performance":1,"crashlytics":2,"sessionSamplingRate":1.0},"firebaseInstallationId":"installId","firebaseAuthenticationToken":"token"},"applicationInfo":{"appId":"appId","deviceModel":"Android SDK built for arm64","sessionSdkVersion":"2.0.0","osVersion":"10","logEnvironment":3,"androidAppInfo":{"packageName":"packageName","versionName":"9.72.0+471-LOCAL-Staging-Debug","appBuildVersion":"471","deviceManufacturer":"Google","currentProcessDetails":{"processName":"packageName","pid":20400,"importance":100,"defaultProcess":true},"appProcessDetails":[{"processName":"packageName","pid":20400,"importance":100,"defaultProcess":true}]}}}

One funny thing is that it writes in the log that the SDK version for CIO is 3.11.1, even if in our configuration it's customerIo = "4.0.0"

remi-ollivier commented 2 months ago

Hi. Did it help you in any way? Do you need more things from us?

Shahroz16 commented 2 months ago

@remi-ollivier we are unable to reproduce it, can you please create a sample app which we could use to reproduce it? It would speed up our efforts on this by a lot.

laurentlr commented 1 month ago

For the record, the issue was coming from the below option we had in our project.

packagingOptions {
   exclude 'kotlin/collections/collections.kotlin_builtins'
}
remi-ollivier commented 1 month ago

We finally updated our app to 4.2.0. We'll keep you updated if we have any existing/new crash

remi-ollivier commented 2 weeks ago

Hi @Shahroz16 we have new crashes

        Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.os.Parcel.dataSize()' on a null object reference
       at android.os.BaseBundle.<init>(BaseBundle.java:126)
       at android.os.Bundle.<init>(Bundle.java:102)
       at android.content.Intent.getExtras(Intent.java:5724)
       at io.customer.messagingpush.ModuleMessagingPushFCM$subscribeToLifecycleEvents$1$2.emit(ModuleMessagingPushFCM.kt:38)
       at io.customer.messagingpush.ModuleMessagingPushFCM$subscribeToLifecycleEvents$1$2.emit(ModuleMessagingPushFCM.kt:35)
       at io.customer.messagingpush.ModuleMessagingPushFCM$subscribeToLifecycleEvents$1$invokeSuspend$$inlined$filter$1$2.emit(Emitters.kt:223)
       at kotlinx.coroutines.flow.SharedFlowImpl.collect$suspendImpl(SharedFlow.kt:397)
       at kotlinx.coroutines.flow.SharedFlowImpl$collect$1.invokeSuspend(SharedFlow.kt:13)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
       at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:102)
       at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.java:589)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:816)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:720)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:707)

and

   Fatal Exception: java.lang.IllegalArgumentException:
       at android.os.Parcel.nativeAppendFrom(Parcel.java)
       at android.os.Parcel.appendFrom(Parcel.java:466)
       at android.os.BaseBundle.<init>(BaseBundle.java:164)
       at android.os.Bundle.<init>(Bundle.java:106)
       at android.content.Intent.getExtras(Intent.java:7025)
       at io.customer.messagingpush.ModuleMessagingPushFCM$subscribeToLifecycleEvents$1$2.emit(ModuleMessagingPushFCM.kt:38)
       at io.customer.messagingpush.ModuleMessagingPushFCM$subscribeToLifecycleEvents$1$2.emit(ModuleMessagingPushFCM.kt:35)
       at io.customer.messagingpush.ModuleMessagingPushFCM$subscribeToLifecycleEvents$1$invokeSuspend$$inlined$filter$1$2.emit(Emitters.kt:223)
       at kotlinx.coroutines.flow.SharedFlowImpl.collect$suspendImpl(SharedFlow.kt:397)
       at kotlinx.coroutines.flow.SharedFlowImpl$collect$1.invokeSuspend(SharedFlow.kt:13)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
       at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:102)
       at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.java:589)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:816)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:720)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:707)

Do you have any idea why and how to solve them? They happened with SDK version 4.2.0 and several Android devices and versions

Shahroz16 commented 2 weeks ago

@remi-ollivier can you please open another ticket with the error trace? otherwise your issues will get lost in notifications 😞