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

isUserless doesn't work properly #210

Closed
mpivchev opened this issue Jan 7, 2018 · 12 comments
Closed

isUserless doesn't work properly #210

mpivchev opened this issue Jan 7, 2018 · 12 comments
Labels
Milestone

Comments

@mpivchev
Copy link

mpivchev commented Jan 7, 2018

When I first open the app, I switchToUserless and when I call isUserless it returns true.
However, when I open the app and switchToUserless again, all of a sudden `isUserless' now returns false, even though that's not true.

Examples

When app opens for the first time:
image

Second time:
image

Also, because isUserless doesn't work properly, my app proceeds to load the account data of the userless account that doesn't exist, and crashes.

Is this how it's supposed to be, since before 1.0.0 isUserless always returned true if the app was not authenticated with a user account

@mattbdean
Copy link
Owner

Can you post the relevant code?

@mpivchev
Copy link
Author

mpivchev commented Jan 7, 2018

There isn't anything else besides this

 private static class AuthenticateAsUserlessTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... voids) {
            try {
                App.getAccountHelper().switchToUserless();
            } catch (OAuthException e) {
                e.printStackTrace();
            }

            return null;
        }
    }

And this

 public static boolean hasUser() {
        Log.d(TAG, "isUserless: " + String.valueOf(App.getAccountHelper().getReddit().getAuthMethod().isUserless()));
        return !App.getAccountHelper().getReddit().getAuthMethod().isUserless();
    }

@mattbdean
Copy link
Owner

Gonna need a bit more context here. When is AuthenticateAsUserlessTask executed? What about hasUser?

@mpivchev
Copy link
Author

mpivchev commented Jan 7, 2018

I call it on onResume where I authenticate as userless (just for now just as I am testing) and after that load the user data (which of course won't be done if the boolean returned the right thing)

 @Override
    protected void onResume() {
        super.onResume();
        AccountManager.getInstance().authenticateUserless();
        AccountManager.getInstance().loadUserData();
    }
 public void loadUserData() {
        new LoadUserDataTask(this).execute();
    }

    /**
     * Fetches user data from Reddit
     */
    private static class LoadUserDataTask extends AsyncTask<Void, Void, Account> {
        private WeakReference<AccountManager> weakAccountManager;

        private LoadUserDataTask(AccountManager weakAccountManager) {
            this.weakAccountManager = new WeakReference<>(weakAccountManager);
        }

        @Override
        protected Account doInBackground(Void... voids) {
            try {
                return App.getAccountHelper().getReddit().me().about();
            } catch (IllegalStateException e) {
                Log.e(TAG, "No user data found, continuing without one");
                return null;
            }
        }

        @Override
        protected void onPostExecute(Account data) {
            if (hasUser()) {
                for (onUserDataReceivedListener l : weakAccountManager.get().listenerList) {
                    l.onUserDataLoaded(data);
                }
            }
        }
    }
  AccountManager.getInstance().addOnUserDataReceivedListener(data -> {
            header.navHeaderUsername.setText(data.getName());
            header.navPostKarma.setText(String.valueOf(data.getLinkKarma()));
            header.navCommentKarma.setText(String.valueOf(data.getCommentKarma()));

            logInButton.setText(data.getName());
        });

@mpivchev
Copy link
Author

mpivchev commented Jan 8, 2018

So, any way to resolve this?

@mattbdean
Copy link
Owner

The reason RedditClient.me() throws an IllegalStateException is because the SelfUserReference constructor calls RedditClient.requireAuthenticatedUser(). This exception only gets thrown when in userless mode.

Since LoadUserDataTask.doInBackground returns null to handle IllegalStateExceptions, you can infer that if the Account passed to onPostExecute is null, there is no authenticated user.

@mpivchev
Copy link
Author

mpivchev commented Jan 8, 2018

True, but that doesn't explain why isUserless returns false, when clearly the app is in userless mode

@mattbdean
Copy link
Owner

Can you log the value of getAuthMethod()? Also Log.e takes a Throwable as a 3rd parameter, I'm going to need it's message and stacktrace.

@mpivchev
Copy link
Author

mpivchev commented Jan 9, 2018

Not quite sure what you mean by Log.e. Print the stacktrace of what?

Here is what it prints. I am userless since currentUsername returns <userless>, but isUserless says otherwise. If a user did exist, then Account.getName() wouldn't be null.

image

@mpivchev mpivchev changed the title isUserless doesn't work properly? isUserless doesn't work properly Jan 9, 2018
@mattbdean mattbdean added bug and removed question labels Jan 10, 2018
@mattbdean
Copy link
Owner

I think I've found the issue. When switchToUserless is called, it first tries to see if the TokenStore has an unexpired access token. If it finds one, it creates a new RedditClient with that data. The issue is that when it finds this data, it uses the wrong Credentials to instantiate it:

return switch(RedditClient(http, current, creds, tokenStore, username))

(source)

Here creds refers to the Credentials originally given to the AccountHelper (with AuthMethod APP). It should be using userlessCreds (with AuthMethod USERLESS_APP) instead.

I should have this fixed by tomorrow.

@mattbdean mattbdean added this to the v1.1.0 milestone Jan 10, 2018
@mpivchev
Copy link
Author

I think RedditClient.setAutoRenew doesn't work properly as well, since it didn't renew the access token automatically when I tried it today, so I'm forced to renew it manually. I will create a new issue tomorrow regarding this after testing a bit more.

@mattbdean
Copy link
Owner

mattbdean commented Jan 11, 2018

Fixed! To use this patch you can either wait until v1.1.0 or use JitPack:

repositories {
    maven { url 'https://jitpack.io' }
}
dependencies {
    compile 'com.github.mattbdean:JRAW:6977732'
}

If you find an issue with setAutoRenew please submit a bug report so I can fix it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants