Repository navigation
feat: add setUserJwtProvider and update Intercom SDKs (iOS 19.9.0, Android 18.10.0) - #471
Conversation
…d: 18.9.3 → 18.10.0) Bumps the package to 10.8.0 for the new user JWT provider API these releases add. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lets apps hand Intercom a fresh user JWT when the current one is about to expire or has expired, so failed requests are retried instead of leaving the Messenger broken. Native sends JS a request with an ID and JS answers it; requests fail fast when JS can't be reached or the React context is torn down. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Nice work, this reads cleanly and the JS test coverage is great. The request/response bridge is mirrored well across iOS and Android, and the version bumps are all consistent. A few non-blocking robustness notes: 1. No timeout cleanup of pending requests (iOS + Android).
Do we know whether a late/double call into the SDK's completion block is a guaranteed no-op? If it isn't, it'd be worth dropping stale entries after a timeout. This is the one I'd most want to confirm against the native SDKs. 2. Empty 3. Listener registered before the native call resolves ( 4. Android uses Only #1 feels worth chasing before merge; the rest are minor. |
|
Followed up on #1 by checking the native SDK contracts directly. Mostly a non-issue: the wrapper already removes each pending entry before invoking its completion, so JS double-replies for the same request are a no-op on both platforms. On Android the SDK explicitly contracts "calls after the first are ignored" (state-guarded + tested), including the Two small adds unrelated to the above: the SDKs apply a ~30s failure cool-down after a timeout/failure that the README doesn't mention (relevant for providers that can take >10s), and #2/#3/#4 remain minor robustness nits. |
Stops listening for JWT requests when native rejects the registration, warns when the provider throws instead of failing silently, and notes the 30s cool-down after a failed or slow provider in the README. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lets the example set a user JWT and register a provider that returns a staged JWT, with a counter of provider calls, to exercise the new API by hand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks! Taking these in order:
Also documented the 30s cool-down in the README. |
|
Thanks for the quick turnaround, the fixes all look good:
One new thing I noticed on a re-read, non-blocking: iOS If you want to close it, funneling |
Keeps all access to the pending-request map on the main queue even when an app enables synchronous void TurboModule methods, which would otherwise run the completion on the JS thread. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks for the re-read! With default settings this one doesn't race: The one exception is an app that opts into |
niamh-coleman
left a comment
There was a problem hiding this comment.
LGTM ✅ Nice work on this, especially catching the sync-void-TurboModule main-queue race on iOS yourself.
I verified the native SDK contracts directly against source: removeUserJwtProvider is a real public API on both platforms, and late/double callback invocations are a safe no-op on Android (state-guarded with a dedicated test suite), with iOS documenting tolerance for late single answers. The JS/native bridge, version bumps, and iOS/Android parity all check out, and CI is green including unit tests.
Two minor, non-blocking residuals worth being aware of (fine to merge as-is):
- On Android the provider lambda retains the
ReactApplicationContextand the pending-request maps arestatic, so stale callbacks can outlive a Fast Refresh / context recreation.invalidate()fails pending requests on teardown, so production impact is negligible, it's mostly a dev-time nit. - The one path the iOS 19.9.0 header doesn't explicitly document is a genuine double-resolution (
setUserJwt:completing a pending request out-of-band, then JS also replying into the stored completion). Android proves that case safe and iOS very likely matches, but if you want certainty it's worth a quick word with the iOS SDK team. Not a blocker.
Approving. 🚀
Why?
iOS 19.9.0 and Android 18.10.0 let the SDK ask the app for a fresh user JWT when the current one is about to expire or has expired, then retry the requests that failed. React Native apps can't use this yet, so an expired JWT leaves the Messenger broken until the app happens to set a new one. This also picks up every native release since iOS 19.8.1 and Android 18.9.3, and ships as 10.8.0.
How?
The app registers an async function that returns a fresh JWT or
null; when the SDK needs one, native sends JS a request with an ID and JS answers back with that ID. If JS can't be reached or the React context goes away, native tells the SDK the request failed instead of leaving it waiting.Generated with Claude Code