Getting authorization error when cancelling from twitter authorization using Fabric SDK

twitterkit

#1

I use Twitter SDK from Fabric for my android application.

I use TwitterAuthClient to have the user log in using Twitter account, and when I cancel the authorization and try to do it again, I get the following error: "Authorize already in progress"
10707-10707 W/Twitter﹕ Authorize already in progress
10707-10707 E/Twitter﹕ Authorization completed with an error
com.twitter.sdk.android.core.TwitterAuthException: Authorize failed.
at com.twitter.sdk.android.core.identity.TwitterAuthClient.handleAuthorize(TwitterAuthClient.java:93)
at com.twitter.sdk.android.core.identity.TwitterAuthClient.authorize(TwitterAuthClient.java:84)
at .OnboardingFriendsListFragment$7.onClick(OnboardingFriendsListFragment.java:402)
at android.view.View.performClick(View.java:4470)
at android.view.View$PerformClick.run(View.java:18599)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5633)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:896)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:712)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
at dalvik.system.NativeStart.main(Native Method)


#2

Hm, sounds like it’s not getting canceled cleanly. Are you using the Login Button to authorize, and are you calling the button’s onActivityResult() method in your Activity’s onActivityResult() method? Or are you implementing login in some other way?


#3

Like I mentioned, I use TwitterAuthClient to authorize instead of the Login Button.

I do call onActivityResult from TwitterAuthClient class, and it works as expected because it was fine when I went ahead with authorizing my account.


#4

Hi there @raylee4204,

It looks like you’re using a Fragment, are you calling onActivityResult() in the Activity hosting the Fragment? Take a look at the special note at https://dev.twitter.com/twitter-kit/android/twitter-login on how to pass the activity result to your fragment holding the log in button.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
 
    // Pass the activity result to the fragment, which will
    // then pass the result to the login button.
    Fragment fragment = getFragmentManager()
                .findFragmentById(R.id.your_fragment_id);
    if (fragment != null) {
        fragment.onActivityResult(requestCode, resultCode, data);
    }
}

#5

I’m having the same issue, I am passing the Activity’s call to my fragment and calling super in the fragment but I don’t have any object to call .onActivityResult on for twitter.

I am just using TwitterCore to fire up the login. Don’t see a way to get a reference to the TwitterAuthClient it is using?

TwitterCore.getInstance().logIn(getActivity(), new Callback<TwitterSession>() {...}

#6

Hi cwrdid,

Instead of calling logIn, you can create a TwitterAuthClient that you can use to call authorize() on, and then use that same object to call onActivityResult().


#7

This is still very much an issue - and I don’t believe your suggestions are to the point…

I have followed the docs, and tested various scenarios of passing back to onActivityResult.

I have a twitter login button, on a fragment, when CANCELLING out of the login screen…

  1. I call from hosting activity receiving onActivityResult, back to the fragment’s onActivityResult
  2. Then inside the fragment, in onActivityResult, I call onActivityResult to twitter login button’s onActivityResult

This will throw an exception without crashing - internally in TwitterCore - everything works correctly though

My concern is I want to remove the ugly exception putting garbage in my logs & analytics?!

com.twitter.sdk.android.core.TwitterAuthException: Authorize failed.
at com.twitter.sdk.android.core.identity.AuthHandler.handleOnActivityResult(AuthHandler.java:80)
at com.twitter.sdk.android.core.identity.TwitterAuthClient.onActivityResult(TwitterAuthClient.java:144)
at com.twitter.sdk.android.core.identity.TwitterLoginButton.onActivityResult(TwitterLoginButton.java:114)


#9

Is there a way we could manually end the authentication session?

My issue is the same, I have implemented a TwitterAuthClient and calls on authorize. When in the SSO screen of the native app, you minimize the app, and launch the app from the start again. From that point on, this issue will arise and the only way for one to proceed is to close the app.


#10

I’ve just had a dig through the Twitter code and come up with a workaround, it’s not 100% as clean as I would like but I didn’t want to use reflection to clear the authentication in progress (which is what TwitterLoginButton does).

The problem is TwitterCore.getInstance().logIn() creates an instance of TwitterAuthClient that we don’t get access to in order to grab a reference its internal AuthState which provides the method to endAuthorize() and allow the user to try again. TwitterLoginButton does provide a mechanism to do this by handling our onActivityResult() response.

The good news is the default constructor for TwitterAuthClient uses a whole load of singletons/static instances, so all we need to do is construct our own to mimic this behaviour. e.g.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    // handle cancelled Twitter login (resets TwitterCore.*AuthHandler.AuthState)
    final TwitterAuthClient twitterAuthClient = new TwitterAuthClient();
    if(twitterAuthClient.getRequestCode()==requestCode) {
        twitterLoginWasCanceled = (resultCode == RESULT_CANCELED);
        twitterAuthClient.onActivityResult(requestCode, resultCode, data);
    }
}

Note that AuthHandler which ends up acting on the resultCode treats RESULT_CANCELLED as an error which ends up triggering the TwitterCore.getInstance().login()'s Callback.failure() passing a TwitterAuthException (a bug?). This is why I catch the RESULT_CANCELLED above, so that I know to ignore the error when it happens.


#11

A post was split to a new topic: Getting auth error on cancel on Twitter Authorization


#13

Hello, I’m trying to integrate twitter using fabric. I’m using twitter button. On clicking button I’m getting error
" Authorization completed with an error com.twitter.sdk.android.core.twitterAuthException: Authorize failed "

I’m using activity (no fragment) and my keys are automatically generated by fabric. I’m calling onActivityResult method also but everytime it is going to failure method of callback.
What can i do please help!
Stuck in this process since last week!


Android: E/Twitter﹕ Authorization completed with an error
#14

I’m moving this to the correct thread for Twitter related SDK questions.


#15

I’ve tried your workaround (not sure how that will solve the problem) and still have the same problem. I also looked at the TwitterLoginButton source code and nowhere do I see reflection being used.

Do you know of the correct way to do reflection to call the endAuthorize() method?

Or maybe explain a bit more how your workaround solves the issue?

Thanks for the help.


#16

Here is the correct way to do it using reflection, found here: https://github.com/twitter/twitter-kit-android/issues/76
(thanks to nishkarsh! https://github.com/nishkarsh)

private void endAuthorizeInProgress() {
        try {
            Field authStateField = twitterAuthClient.getClass().getDeclaredField("authState");
            authStateField.setAccessible(true);
            Object authState = authStateField.get(twitterAuthClient);
            Method endAuthorize = authState.getClass().getDeclaredMethod("endAuthorize");
            endAuthorize.invoke(authState);
        } catch (NoSuchFieldException | SecurityException | InvocationTargetException |
                NoSuchMethodException | IllegalAccessException e) {
            logger.e("Couldn't end authorize in progress.", e);
        }
    }

#17

Hi, I’m pretty sure my workaround won’t work on the current SDK as it was 3 years old.


#18

In the next release of Twitter Kit you will be able to explicitly call endAuthorize(). Please see this PR for reference.


#19