AccountManager - authToken is set but peekAuthToken return null
Asked Answered
H

1

6

I'm trying to add a new account (after a Facebook login + server validation) in AccountManager. The flow for this case is like this:

  1. User login with Facebook
  2. I got the details after the login is done and I validate them against the data I have on my server
  3. If everything is ok, the server send back an auth_token (JWT token)
  4. Having user's details and the auth_token I'm creating an account via AccountManager and once it is created, I set the authToken for it.
  5. On next login when the user will re-open the app I call getAuthToken which first try to get the cached authToken by calling peekAuthToken().

The problem

At point 5, peekAuthToken returns null but it shouldn't because I already set the autToken for that account.

Code

 public static Bundle handleUserLogin(Context context, User user) {
    SharedPreferences mPrefs = context.getSharedPreferences(Constants.PREFS_NAME, Context.MODE_PRIVATE);
    AccountManager am = AccountManager.get(context);
    Account account = new Account(user.getEmail(), ACCOUNT_TYPE);
    Account[] accounts = am.getAccountsByType(ACCOUNT_TYPE);
    boolean isNewAccount = true;


    for (int i = 0; i < accounts.length; i++) {
        if (user.getEmail().equalsIgnoreCase(accounts[i].name) && ACCOUNT_TYPE.equalsIgnoreCase(accounts[i].type)) {
            isNewAccount = false;
            account = accounts[i];
            break;
        }
    }

    if (isNewAccount) {
        am.addAccountExplicitly(account, user.getPassword(), null);
        accounts = am.getAccountsByType(ACCOUNT_TYPE);

        for (int i = 0; i < accounts.length; i++) {
            if (user.getEmail().equalsIgnoreCase(accounts[i].name) && ACCOUNT_TYPE.equalsIgnoreCase(accounts[i].type)) {
                account = accounts[i];
                break;
            }
        }
    }

    if (null != user.getPassword()) {
        am.setPassword(account, user.getPassword());
    }

    Cs.error(TAG, "account " + account + " token " + user.getToken());
    am.setAuthToken(account, user.getToken(), Authenticator.AUTHTOKEN_TYPE_FULL_ACCESS);
    setUserData(user, account, am);

    Bundle result = new Bundle();

    result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
    result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
    result.putString(AccountManager.KEY_AUTHTOKEN, user.getToken());
    mPrefs.edit().putString(Constants.KEY_CURRENT_USER, account.name).commit();

    return result;
}

First I thought that maybe the reference to my new account is not the correct one (ex the one from AccountManager) so I search for account again.

Could you give me some indications about what I'm doing wrong or how should I make sure the authToken will be set for an account?

Thank you

Handshaker answered 12/5, 2015 at 6:35 Comment(0)
E
0

I would not rely on explicit setting authToken in place different than in AbstractThreadedAccountAuthenticator's getAuthToken() method. My guess is that the authToken is not cached yet when you request it.

I suggest just creating account via AccountManager.addAccountExplicitly() and deferring accessing authToken once you really need it.

In AbstractThreadedAccountAuthenticator's getAuthToken() I suggest applying logic like in the project I created a while ago.

  1. Request authToken via AccountManager.peekAuthToken()
  2. If authToken is set in cache then return it.
  3. If not then request it from your server then cache via AccountManager.setAuthToken() and finally return.

Link: https://github.com/dawidgdanski/AccountAuthenticatorExample/blob/master/app/src/main/java/com/authenticator/account/auth/SimpleAuthenticator.java

Hope this will help you out:

https://github.com/dawidgdanski/AccountAuthenticatorExample

Erythro answered 12/5, 2015 at 7:57 Comment(1)
Please include some explaination in your answer as well. I think you're talking about github.com/dawidgdanski/AccountAuthenticatorExample/blob/master/… ?Lavery

© 2022 - 2024 — McMap. All rights reserved.