diff --git a/crates/ubrn_cli/templates/jsi/android/cpp-adapter.cpp b/crates/ubrn_cli/templates/jsi/android/cpp-adapter.cpp
index d8d1c1a1c1269ecee9467fd0ef809dcb1e375923..a031428d1eaecec2df94e7148e9d45d15642158d 100644
--- a/crates/ubrn_cli/templates/jsi/android/cpp-adapter.cpp
+++ b/crates/ubrn_cli/templates/jsi/android/cpp-adapter.cpp
@@ -2,6 +2,7 @@
 #include <jni.h>
 #include <jsi/jsi.h>
 #include <ReactCommon/CallInvokerHolder.h>
+#include <fbjni/fbjni.h>
 #include "{{ self.config.project.cpp_filename() }}.h"
 {%- let package_name = self.config.project.android.package_name().replace(".", "_") %}
 {%- let name = self.config.project.module_cpp() %}
@@ -29,35 +30,27 @@ JNIEXPORT jboolean JNICALL
     jlong rtPtr,
     jobject callInvokerHolderJavaObj
 ) {
-    // https://github.com/realm/realm-js/blob/main/packages/realm/binding/android/src/main/cpp/io_realm_react_RealmReactModule.cpp#L122-L145
-    // React Native uses the fbjni library for handling JNI, which has the concept of "hybrid objects",
-    // which are Java objects containing a pointer to a C++ object. The CallInvokerHolder, which has the
-    // invokeAsync method we want access to, is one such hybrid object.
-    // Rather than reworking our code to use fbjni throughout, this code unpacks the C++ object from the Java
-    // object `callInvokerHolderJavaObj` manually, based on reverse engineering the fbjni code.
-
-    // 1. Get the Java object referred to by the mHybridData field of the Java holder object
-    auto callInvokerHolderClass = env->GetObjectClass(callInvokerHolderJavaObj);
-    auto hybridDataField = env->GetFieldID(callInvokerHolderClass, "mHybridData", "Lcom/facebook/jni/HybridData;");
-    auto hybridDataObj = env->GetObjectField(callInvokerHolderJavaObj, hybridDataField);
-
-    // 2. Get the destructor Java object referred to by the mDestructor field from the myHybridData Java object
-    auto hybridDataClass = env->FindClass("com/facebook/jni/HybridData");
-    auto destructorField =
-        env->GetFieldID(hybridDataClass, "mDestructor", "Lcom/facebook/jni/HybridData$Destructor;");
-    auto destructorObj = env->GetObjectField(hybridDataObj, destructorField);
-
-    // 3. Get the mNativePointer field from the mDestructor Java object
-    auto destructorClass = env->FindClass("com/facebook/jni/HybridData$Destructor");
-    auto nativePointerField = env->GetFieldID(destructorClass, "mNativePointer", "J");
-    auto nativePointerValue = env->GetLongField(destructorObj, nativePointerField);
-
-    // 4. Cast the mNativePointer back to its C++ type
-    auto nativePointer = reinterpret_cast<facebook::react::CallInvokerHolder*>(nativePointerValue);
-    auto jsCallInvoker = nativePointer->getCallInvoker();
-
-    auto runtime = reinterpret_cast<jsi::Runtime *>(rtPtr);
-    return {{ ns }}::installRustCrate(*runtime, jsCallInvoker);
+    try {
+        if (callInvokerHolderJavaObj == nullptr) {
+            return false;
+        }
+
+        auto alias = facebook::jni::alias_ref<jobject>(callInvokerHolderJavaObj);
+        auto holder = facebook::jni::static_ref_cast<facebook::react::CallInvokerHolder::javaobject>(alias);
+        if (!holder) {
+            return false;
+        }
+
+        auto jsCallInvoker = holder->cthis()->getCallInvoker();
+        if (!jsCallInvoker) {
+            return false;
+        }
+
+        auto runtime = reinterpret_cast<jsi::Runtime *>(rtPtr);
+        return {{ ns }}::installRustCrate(*runtime, jsCallInvoker);
+    } catch (...) {
+        return false;
+    }
 }
 
 extern "C"
