braintree-android-drop-in: 6.5.0 DropInClient - Method addObserver must be called on the main thread

I am working on react native module for DropIn and getting this error on initialization of DropInClient

implementation "com.braintreepayments.api:drop-in:6.5.0

         val dropInClient = DropInClient(currentActivity as AppCompatActivity?,clientToken)
         

Method addObserver must be called on the main thread

Why this error can appear?

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Comments: 18 (7 by maintainers)

Most upvoted comments

@Kowshika-aspire I can see now how this makes it difficult to use DropIn with React Native.

We may have to consider this as a feature request for our next major version. Would the ideal DropIn API for React Native be to allow authorization as a DropInRequest parameter? Also are you able to use 5.x in the meantime?

@zhenghow93 yes. We made a small patch to include the latest version of the Cardinal SDK to help extend the migration window for merchants.

Hi @molchanovskiy @sshropshire

I have followed the same solution which is given by @molchanovskiy. But the problem I’m facing is, dropInClient.setListener is not triggered once I completed the payment. Both onDropInSuccess and onDropInFailure is not triggered.

My Mainactivity snippet:

  public static DropInClient client = null;
  public static String token = "";

client=new DropInClient(this, new ClientTokenProvider() {
           @Override
           public void getClientToken(@NonNull ClientTokenCallback callback) {
               callback.onSuccess(token);
           }
       });

In module call:

DropInClient dropInClient = MainActivity.client;
       dropInClient.invalidateClientToken();
       dropInClient.setListener(new DropInListener() {
           @Override
           public void onDropInSuccess(@NonNull DropInResult dropInResult) {
               resolvePayment(dropInResult, jsPromise);
           }

           @Override
           public void onDropInFailure(@NonNull Exception error) {
               if (error.hashCode() == Activity.RESULT_CANCELED) {
                   jsPromise.reject("USER_CANCELLATION", "The user cancelled");
               } else {
                   jsPromise.reject(error.getMessage(), error.getMessage());
               }

           }
       });
       dropInClient.launchDropIn(dropInRequest);

Please look into this issue.

@wayson I found a solution. You can init the drop in client with an empty token in onCreate() of Activity with shared instance and then use it inside the module by providing token and calling invalidateClientToken which will trigger fetch client token callback.

Activity onCreate():

      val dropInClient = DropInClient(this, ClientTokenProvider { callback ->
            // fetch client token asynchronously...
            callback.onSuccess(BraintreeSharedInstance.instance.clientToken);
        })
        BraintreeSharedInstance.instance.dropInClient = dropInClient
    Module call:
        BraintreeSharedInstance.instance.clientToken = token
          val dropInClient:DropInClient? = BraintreeSharedInstance.instance.dropInClient
          dropInClient?.invalidateClientToken()
          dropInClient?.setListener(PaymentDropInListener())
          dropInClient?.launchDropIn(dropInRequest)