Skip to content

Guard deconstructRegistration against null Registration#451

Merged
imSzukala merged 1 commit into
mainfrom
fix/android-fetchloggedinuserattributes-npe
Jun 16, 2026
Merged

Guard deconstructRegistration against null Registration#451
imSzukala merged 1 commit into
mainfrom
fix/android-fetchloggedinuserattributes-npe

Conversation

@imSzukala

Copy link
Copy Markdown
Contributor

What

Adds a null guard at the top of IntercomHelpers.deconstructRegistration(...) so it returns an empty WritableMap when the Registration is null, instead of crashing.

Why

Intercom.client().fetchLoggedInUserAttributes() returns null by design when no user is logged in — the native Android SDK documents this (fetchLoggedInUserAttributes(): Registration?). This happens, for example, after the OS kills and restarts the app process (clearing the in-memory native session) and the app calls fetchLoggedInUserAttributes() before re-registration completes.

Both oldarch and newarch IntercomModule.fetchLoggedInUserAttributes() pass that return value straight into deconstructRegistration(...):

Registration registration = Intercom.client().fetchLoggedInUserAttributes(); // can be null
promise.resolve(IntercomHelpers.deconstructRegistration(registration));       // no null check

deconstructRegistration then dereferences registration.getEmail() on its first line, throwing a fatal NullPointerException on the JS bridge thread (UncaughtExceptionHandler → process death).

This is a platform parity gap: the iOS bridge (IntercomAttributesBuilder.dictionaryForUserAttributes:) reads attributes on a possibly-nil ICMUserAttributes and, thanks to Obj-C nil-messaging, resolves an empty dictionary ({}) for the same "no logged-in user" case. The fix brings Android to the same behavior, which also satisfies the existing non-nullable TS contract fetchLoggedInUserAttributes: () => Promise<UserAttributes>.

The native Android SDK is correct and unchanged — the nullable return is by design; only the RN bridge needed the guard. Pre-existing bug, not a regression (present in every release from 9.8.0 onward).

Crash (production)

java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.String io.intercom.android.sdk.identity.Registration.getEmail()' on a null object reference
  at com.intercom.reactnative.IntercomHelpers.deconstructRegistration
  at com.intercom.reactnative.IntercomModule.fetchLoggedInUserAttributes

Tests

The android/ library module has no JUnit/Robolectric test harness, and deconstructRegistration depends on RN's Arguments.createMap() bridge runtime. Standing up a test harness is out of scope for this one-line fix; the change is a straightforward null guard with a behavior matching the already-shipped iOS path.

Related

  • Internal issue: intercom/intercom#520691

~ Automated via Claude

Intercom.client().fetchLoggedInUserAttributes() returns null when no user
is logged in (e.g. after the OS kills and restarts the process, clearing
the native session). Both the oldarch and newarch IntercomModule pass that
return value straight into IntercomHelpers.deconstructRegistration(), which
immediately calls registration.getEmail() and throws a fatal
NullPointerException on the JS bridge thread.

Return an empty map when registration is null, matching the iOS bridge,
which resolves an empty dictionary for the same "no logged-in user" case.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@imSzukala imSzukala merged commit c6ed239 into main Jun 16, 2026
8 checks passed
@imSzukala imSzukala deleted the fix/android-fetchloggedinuserattributes-npe branch June 16, 2026 12:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants