Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android Crash - "Callback arg cannot be called more than once"; #601

Open
mobinni opened this issue Jan 15, 2025 · 7 comments
Open

Android Crash - "Callback arg cannot be called more than once"; #601

mobinni opened this issue Jan 15, 2025 · 7 comments

Comments

@mobinni
Copy link

mobinni commented Jan 15, 2025

Report

Plugin Version

6.15.1

On what Platform are you having the issue?

Android only

What did you do?

We use logEvent

What did you expect to happen?

logEvent callbacks not to crash on Android

What happened instead?

On new arch in production for Android we receive crash logs where onError callback is called, but invoked twice which causes a crash to trigger;

react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp
      if (!callback) {
          LOG(FATAL) << "Callback arg cannot be called more than once";
          return;
        }
  #10  pc 0x000000000060cb00  /data/app/~~fd4r20TdR3MOOG2sjAaVtg==/com.wealthsimple.trade-dfI26diei0-qwrUPNR0eeg==/base.apk (com.facebook.react.bridge.CxxCallbackImpl.invoke+8)
  #11  pc 0x0000000000780ee4  /apex/com.android.art/lib64/libart.so (nterp_helper+7540)
  #12  pc 0x0000000000879a18  /data/app/~~fd4r20TdR3MOOG2sjAaVtg==/com.*.*-dfI26diei0-qwrUPNR0eeg==/base.apk (com.appsflyer.reactnative.RNAppsFlyerModule$3.onError+12)
  #13  pc 0x0000000000780ee4  /apex/com.android.art/lib64/libart.so (nterp_helper+7540)
  #14  pc 0x0000000000861500  /data/app/~~fd4r20TdR3MOOG2sjAaVtg==/com.*.*-dfI26diei0-qwrUPNR0eeg==/base.apk (com.appsflyer.internal.AFf1pSDK.AFAdRevenueData+116)

Please provide any other relevant information.

Im not sure how the double invocation happens, based on google play console it happens mostly on backgrounding. I could repro the issue by manually double invoking a callback. Based on the codepaths I see that we trigger the error callback in the try / catch as well as onError, there might be some type of condition being hit here where the error happens in logEvent natively gets thrown up and handled again?

@mobinni
Copy link
Author

mobinni commented Feb 5, 2025

@amit-kremer93

@markstreich
Copy link

Same with 6.15.3 (expo 52.0.31), we're slowly rolling out a new version and seeing a few of these

The stack trace looks like this

==/base.apk (com.facebook.react.bridge.CxxCallbackImpl.invoke+8)
==/base.apk (com.appsflyer.reactnative.RNAppsFlyerModule$3.onError+12)
==/base.apk (com.appsflyer.internal.AFf1oSDK.getCurrencyIso4217Code+116)
==/base.apk (com.appsflyer.internal.AFe1eSDK.component3+96)

@mobinni
Copy link
Author

mobinni commented Feb 19, 2025

@markstreich we disabled the double callback as a local patch for remediation

@markstreich
Copy link

@mobinni could you share the patch?

@markstreich
Copy link

Something like this? (I don't know how to recreate it, and don't know java, so kind of flying blind)

--- a/node_modules/react-native-appsflyer/android/src/main/java/com/appsflyer/reactnative/RNAppsFlyerModule.java
+++ b/node_modules/react-native-appsflyer/android/src/main/java/com/appsflyer/reactnative/RNAppsFlyerModule.java
@@ -326,7 +326,7 @@ public class RNAppsFlyerModule extends ReactContextBaseJavaModule {
                 });
             }
         } catch (Exception e) {
-            errorCallback.invoke(e.getMessage());
+            // errorCallback.invoke(e.getMessage());
             return;
         }
     }

@mobinni
Copy link
Author

mobinni commented Feb 20, 2025

diff --git a/node_modules/react-native-appsflyer/android/src/main/java/com/appsflyer/reactnative/RNAppsFlyerModule.java b/node_modules/react-native-appsflyer/android/src/main/java/com/appsflyer/reactnative/RNAppsFlyerModule.java
index 3892ba5..51cca6b 100755
--- a/node_modules/react-native-appsflyer/android/src/main/java/com/appsflyer/reactnative/RNAppsFlyerModule.java
+++ b/node_modules/react-native-appsflyer/android/src/main/java/com/appsflyer/reactnative/RNAppsFlyerModule.java
@@ -304,7 +304,8 @@ public class RNAppsFlyerModule extends ReactContextBaseJavaModule {
             final Callback errorCallback) {
         try {
             if (eventName.trim().equals("")) {
-                errorCallback.invoke(NO_EVENT_NAME_FOUND);
+                // Disable as this is not a valuable error callback
+                // errorCallback.invoke(NO_EVENT_NAME_FOUND);
                 return;
             }
             Map<String, Object> data = RNUtil.toMap(eventData);
@@ -316,18 +317,17 @@ public class RNAppsFlyerModule extends ReactContextBaseJavaModule {
                 AppsFlyerLib.getInstance().logEvent(getCurrentActivity(), eventName, data, new AppsFlyerRequestListener() {
                     @Override
                     public void onSuccess() {
-                        successCallback.invoke(SUCCESS);
+                        // successCallback.invoke(SUCCESS);
                     }
 
                     @Override
                     public void onError(int i, @NonNull String s) {
-                        errorCallback.invoke(s);
+                        // errorCallback.invoke(s);
                     }
                 });
             }
         } catch (Exception e) {
-            errorCallback.invoke(e.getMessage());
-            return;
+            // Do nothing
         }
     }
 
@@ -336,7 +336,8 @@ public class RNAppsFlyerModule extends ReactContextBaseJavaModule {
             final String eventName, ReadableMap eventData, final Promise promise) {
         try {
             if (eventName.trim().equals("")) {
-                promise.reject(NO_EVENT_NAME_FOUND, new Exception(NO_EVENT_NAME_FOUND).getMessage());
+                // Disable as this is not a valuable error callback
+                // promise.reject(NO_EVENT_NAME_FOUND, new Exception(NO_EVENT_NAME_FOUND).getMessage());
                 return;
             }
             Map<String, Object> data = RNUtil.toMap(eventData);
@@ -348,22 +349,21 @@ public class RNAppsFlyerModule extends ReactContextBaseJavaModule {
                 AppsFlyerLib.getInstance().logEvent(getCurrentActivity(), eventName, data, new AppsFlyerRequestListener() {
                     @Override
                     public void onSuccess() {
-                        promise.resolve(SUCCESS);
+                        // promise.resolve(SUCCESS);
                     }
 
                     @Override
                     public void onError(int i, @NonNull String s) {
-                        promise.reject(s);
+                        // promise.reject(s);
                     }
                 });
             }
         } catch (Exception e) {
-            promise.reject(UNKNOWN_ERROR, e);
-            return;
+            // Do nothing
         }
     }

@markstreich
Copy link

Thanks!

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

No branches or pull requests

2 participants