analytics-react-native: Setup fails with 'writeKey must not be null or empty'

Using @segment/analytics-react-native v1.4.3 and @segment/analytics-react-native-intercom v1.4.3.

We recently updated a seemingly unrelated library, react-native-purchases, to v4.1.0. With the update, our app shows a React Native red box on startup with the message ‘writeKey must not be null or empty’.

CatalystInstanceImpl caught native exception
 java.lang.IllegalArgumentException: writeKey
 	at com.segment.analytics.Analytics$Builder.<init>(Analytics.java:108
 	at com.segment.analytics.Analytics.with(Analytics.java:175)
 	at com.segment.analytics.reactnative.core.RNAnalyticsModule
 	at com.segment.analytics.reactnative.core.RNAnalyticsModule.setup(RNAnalyticsModule.kt:207)
 	at java.lang.reflect.Method.invoke(Native Method)
 	at com.facebook.react.bridge.JavaMethodWrapper.in
 	at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:151)
 	at com.facebook.react.bridge.queue.NativeRunnable.run(Native Method)
 	at android.os.Handler.handleCallback(Handler.java:873)
 	at android.os.Handler.dispatchMessage(Handler.java:99)
 	at com.facebook.react.bridge.queue.MessageQueueThreadH
 	at android.os.Looper.loop(Looper.java:193)
 	at com.facebook.react.bridge.queue.Message
 	at java.lang.Thread.run(Thread.java:764)

Debugging RNAnalyticsModule.setup() confirms that writeKey is being passed with a valid value. It also reveals an IllegalStateException being caught and ignored (line 190). While the comment in that catch block reads pass if the error is due to calling setSingletonInstance multiple times. However, the exception has the message java.lang.IllegalStateException: Method addObserver must be called on the main thread_. So it would seem that setup()'s first attempt to initialise a client is silently failing, then when analytics.track() is called from trackApplicationLifecycleEvents(), a second attempt is made to initialise a client which fails, causing the red box error.

Noting that the addObserver() call was surrounded by if (useNewLifecycleMethods) { I tried adding

    android: {
      experimentalUseNewLifecycleMethods: false,

to the call to segment.setup() in RN. This has no effect as experimentalUseNewLifecycleMethods is not passed through by configuration.ts. Modifying the Java code to force this to true causes setup() to appear to complete successfully, though I’ve not verified if there are any other side-effects.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 2
  • Comments: 23 (4 by maintainers)

Most upvoted comments

After digging into that, seems like no change at our end was the cause for this, and it’s only something specific with this package and its dependencies.

I can confirm that @prayansh / @alanjcharles fixes in https://github.com/segmentio/analytics-react-native/pull/298 really worked by changing build.gradle using patch-package.

Here is the patch-package diff that solved my problem (I guess the version bump was the actual solution here):

diff --git a/node_modules/@segment/analytics-react-native/android/build.gradle b/node_modules/@segment/analytics-react-native/android/build.gradle
index a1b26ba..ac18943 100644
--- a/node_modules/@segment/analytics-react-native/android/build.gradle
+++ b/node_modules/@segment/analytics-react-native/android/build.gradle
@@ -39,7 +39,7 @@ repositories {
 }
 
 dependencies {
-    api 'com.segment.analytics.android:analytics:4.9.1-beta'
+    api 'com.segment.analytics.android:analytics:4.9.3'
 
     api 'com.facebook.react:react-native:+'
     api "org.jetbrains.kotlin:kotlin-stdlib:${rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : defaultKotlinVersion}"
diff --git a/node_modules/@segment/analytics-react-native/android/src/main/java/com/segment/analytics/reactnative/core/RNAnalyticsModule.kt b/node_modules/@segment/analytics-react-native/android/src/main/java/com/segment/analytics/reactnative/core/RNAnalyticsModule.kt
index 867a15b..1e01acd 100644
--- a/node_modules/@segment/analytics-react-native/android/src/main/java/com/segment/analytics/reactnative/core/RNAnalyticsModule.kt
+++ b/node_modules/@segment/analytics-react-native/android/src/main/java/com/segment/analytics/reactnative/core/RNAnalyticsModule.kt
@@ -106,6 +106,10 @@ class RNAnalyticsModule(context: ReactApplicationContext): ReactContextBaseJavaM
         val json = options.getString("json")
         val writeKey = options.getString("writeKey")
 
+        if (writeKey == null) {
+            return promise.reject("E_SEGMENT_RECONFIGURED", "writeKey cannot be null")
+        }
+
         if(singletonJsonConfig != null) {
             if(json == singletonJsonConfig) {
                 return promise.resolve(null)
@@ -183,6 +187,8 @@ class RNAnalyticsModule(context: ReactApplicationContext): ReactContextBaseJavaM
             })
         }
 
+        builder.experimentalUseNewLifecycleMethods(false)
+
         try {
             Analytics.setSingletonInstance(
                     RNAnalytics.buildWithIntegrations(builder)

This issue body was partially generated by patch-package.

@prayansh / @alanjcharles Please, please cut a release 😃 this seems like a major issue that might affect many applications, and it seems like something that isn’t possible to catch in ci, reproduce during development, or even reproduce in release mode on some devices, so developers might notice that only when it’s too late.

Hi Everyone,

We have pushed a fix for this here https://github.com/segmentio/analytics-react-native/pull/298

It seems Facebook introduced a breaking change for Kotlin in react-native 0.64 so we are testing to make sure the changes work with older versions in an attempt to maintain our minimum version support at react-native 0.62. Hope to push a new release today or Monday.

Hi- we pushed a the release this morning! Apologies for the delay. Please feel free to reopen if you’re still running into issues and we can take a closer look.

After digging into that, seems like no change at our end was the cause for this, and it’s only something specific with this package and its dependencies.

I can confirm that @prayansh / @alanjcharles fixes in #298 really worked by changing build.gradle using patch-package.

Here is the patch-package diff that solved my problem (I guess the version bump was the actual solution here):

diff --git a/node_modules/@segment/analytics-react-native/android/build.gradle b/node_modules/@segment/analytics-react-native/android/build.gradle
index a1b26ba..ac18943 100644
--- a/node_modules/@segment/analytics-react-native/android/build.gradle
+++ b/node_modules/@segment/analytics-react-native/android/build.gradle
@@ -39,7 +39,7 @@ repositories {
 }
 
 dependencies {
-    api 'com.segment.analytics.android:analytics:4.9.1-beta'
+    api 'com.segment.analytics.android:analytics:4.9.3'
 
     api 'com.facebook.react:react-native:+'
     api "org.jetbrains.kotlin:kotlin-stdlib:${rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : defaultKotlinVersion}"
diff --git a/node_modules/@segment/analytics-react-native/android/src/main/java/com/segment/analytics/reactnative/core/RNAnalyticsModule.kt b/node_modules/@segment/analytics-react-native/android/src/main/java/com/segment/analytics/reactnative/core/RNAnalyticsModule.kt
index 867a15b..1e01acd 100644
--- a/node_modules/@segment/analytics-react-native/android/src/main/java/com/segment/analytics/reactnative/core/RNAnalyticsModule.kt
+++ b/node_modules/@segment/analytics-react-native/android/src/main/java/com/segment/analytics/reactnative/core/RNAnalyticsModule.kt
@@ -106,6 +106,10 @@ class RNAnalyticsModule(context: ReactApplicationContext): ReactContextBaseJavaM
         val json = options.getString("json")
         val writeKey = options.getString("writeKey")
 
+        if (writeKey == null) {
+            return promise.reject("E_SEGMENT_RECONFIGURED", "writeKey cannot be null")
+        }
+
         if(singletonJsonConfig != null) {
             if(json == singletonJsonConfig) {
                 return promise.resolve(null)
@@ -183,6 +187,8 @@ class RNAnalyticsModule(context: ReactApplicationContext): ReactContextBaseJavaM
             })
         }
 
+        builder.experimentalUseNewLifecycleMethods(false)
+
         try {
             Analytics.setSingletonInstance(
                     RNAnalytics.buildWithIntegrations(builder)

This issue body was partially generated by patch-package.

@prayansh / @alanjcharles Please, please cut a release 😃 this seems like a major issue that might affect many applications, and it seems like something that isn’t possible to catch in ci, reproduce during development, or even reproduce in release mode on some devices, so developers might notice that only when it’s too late.

It worked for me!

Hi Everyone,

We have pushed a fix for this here #298

It seems Facebook introduced a breaking change for Kotlin in react-native 0.64 so we are testing to make sure the changes work with older versions in an attempt to maintain our minimum version support at react-native 0.62. Hope to push a new release today or Monday.

Worth mentioning that we are using 0.63.4 and having this issue on Android. Only in release APK, it doesn’t happen during development.

The native call stack for the exception is:

com.segment.analytics.Analytics$Builder in <init> at line 1086
com.segment.analytics.Analytics in with at line 175
com.segment.analytics.reactnative.core.RNAnalyticsModule in getAnalytics at line 44
com.segment.analytics.reactnative.core.RNAnalyticsModule in trackApplicationLifecycleEvents at line 81
com.segment.analytics.reactnative.core.RNAnalyticsModule in setup at line 200

And we are using trackAppLifecycleEvents: true

Hi everyone,

Thanks for all of the feedback! I have been able to reproduce and we are looking into it. I hope to have more information for you by the end of the day or first thing tomorrow. Reopening for now.

I have same problem after updating Stripe dependency to 16.4.3