rive-app / rive-app/rive-react-native

Android bridgeless: all view events fail — getJSModule(RCTEventEmitter) throws on BridgelessReactContext

Open
#437 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
783
Forks
81
Avg merge
3d 6h
Merged PRs (30d)
3

Description

Description

Under bridgeless New Architecture on Android, every event RiveReactNativeView emits throws, because the view emits through the legacy RCTEventEmitter JS module and BridgelessReactContext.getJSModule does not support it.

The practical effect is that onLoop, onStateChanged, onPlay, onStop and onRiveEventReceived never reach JS, with no error surfaced on the JS side — the callback simply never fires. For a looping animation it also produces continuous logcat spam, roughly one stack trace per loop.

Stack trace
E unknown:BridgelessReactContext:
  at com.facebook.react.runtime.BridgelessReactContext.getJSModule(BridgelessReactContext.kt:133)
  at com.facebook.react.uimanager.ThemedReactContext.getJSModule(ThemedReactContext.kt:74)
  at com.rivereactnative.RiveReactNativeView.onLoopEnd(RiveReactNativeView.kt:255)
  at com.rivereactnative.RiveReactNativeView$1.notifyLoop(RiveReactNativeView.kt:128)
  at app.rive.runtime.kotlin.controllers.RiveFileController.notifyLoop(RiveFileController.kt:1022)
  at app.rive.runtime.kotlin.renderers.RiveArtboardRenderer.advance(RiveArtboardRenderer.kt:74)
Cause

RiveReactNativeView.kt dispatches events via reactContext.getJSModule(RCTEventEmitter::class.java). I count nine such call sites in the current release (9.8.5) — lines 222, 233, 244, 255, 265, 304, 493 and 1118, plus the import at line 33:

// android/src/main/java/com/rivereactnative/RiveReactNativeView.kt
33:  import com.facebook.react.uimanager.events.RCTEventEmitter
248: fun onLoopEnd(animationName: String, loopMode: RNLoopMode) {
255:   reactContext.getJSModule(RCTEventEmitter::class.java)

getJSModule throws unconditionally on a BridgelessReactContext, so every one of these paths is dead when newArchEnabled=true.

The usual migration is UIManagerHelper.getEventDispatcherForReactTag(reactContext, viewTag) with an Event subclass, which works under both the bridge and bridgeless.

Versions
  • rive-react-native: 9.8.1, and verified unchanged in 9.8.5 (latest at time of writing) by inspecting the published tarball
  • react-native: 0.81.5
  • Expo SDK 55
  • android/gradle.properties: newArchEnabled=true
  • Reproduced on a release build; a debug build surfaces it differently
Note on #190

#190 is closed and looks related, but it is a different symptom — the "'RiveReactNativeView' is not Fabric compatible yet" banner on RN 0.72 / rive 4.1.2. Rendering works fine here; it is specifically the event dispatch that fails. I could not find an existing issue covering this, but apologies if I have missed one.

Workaround for anyone hitting this

Rendering and autoplay are unaffected, so if you only use Rive decoratively you will see log spam and nothing else. If you depend on a completion callback, drive it from a timer instead and make the handler idempotent, since the native callback may never arrive:

const doneOnce = React.useRef(false);
const handleComplete = React.useCallback(() => {
  if (doneOnce.current) return;
  doneOnce.current = true;
  onComplete();
}, [onComplete]);

// Load-bearing under bridgeless: onStateChanged never fires.
React.useEffect(() => {
  const id = setTimeout(handleComplete, ANIMATION_MS);
  return () => clearTimeout(id);
}, [handleComplete]);

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in android/src/main/java/com/rivereactnative/RiveReactNativeView.kt at the listed RCTEventEmitter call sites, especially onLoopEnd and the stack-trace entry points. Inspect the bridgeless event-dispatch path and verify the reported release configuration; done means all listed callbacks reach JavaScript under bridgeless and bridge configurations without exceptions or recurring logcat spam.

Written by the indexing model from the issue text.

Assessment

Tech stack
kotlin, react-native
Domain
mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
64/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.