Ошибка проверки токена доступа: пользователь не авторизовал приложение. Фейсбук SDK 4

Вот случай:

Если я ранее предоставлял разрешения на чтение моему приложению через

LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("email"));

Затем, когда мне нужно поделиться, я запрашиваю разрешения на публикацию через:

LoginManager.getInstance().logInWithPublishPermissions(getActivity(), Arrays.asList("publish_actions"));

Все работает нормально, пока я не удалил разрешения для своего приложения в Интернете.

Если приложение было убито или остановлено, и мне нужно поделиться, я проверю, есть ли у меня разрешения:

if(userAuthorizedMyApp()){
    LoginManager.getInstance().logInWithPublishPermissions(this, Arrays.asList("publish_actions"));
} else {
    LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("email"));
}

Метод userAuthorizedMyApp() возвращает false (accessToken null):

private boolean userAuthorizedMyApp() {
    boolean authorized;
    AccessToken accessToken = AccessToken.getCurrentAccessToken();
    if(DEBUG) Log.v(TAG, "accessToken [" + accessToken +"]");

    if(accessToken != null){
        Set<String> currentPermissions = accessToken.getPermissions();
        authorized = currentPermissions.contains("public_profile");
    } else {
        authorized = false;
    }
    if(DEBUG) Log.v(TAG, "userAuthorizedMyApp[" + authorized +"]");

    return authorized;
}

И я пытаюсь сделать обычный вход, как будто это был первый раз:

LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("email"));

И я получаю:

public void onError(FacebookException error)

onError, error {HttpStatus: -1, errorCode: 190, errorType: null, errorMessage: Ошибка проверки маркера доступа: пользователь не авторизовал приложение 123456789123456.}

Любые идеи, что я делаю неправильно?


person Danylo Volokh    schedule 23.04.2015    source источник
comment
Когда вы получаете эту ошибку, можете ли вы попробовать очистить токен доступа LoginManager.logout() и повторить вход?   -  person Ming Li    schedule 23.04.2015
comment
На самом деле, при выполнении того же действия во второй раз все работает нормально - открывается экран входа в систему. Но получение ошибки при первой попытке сбивает пользователя с толку.   -  person Danylo Volokh    schedule 26.04.2015
comment
Помните, что токен доступа кэшируется на клиенте, поэтому, если вы на самом деле не сделаете запрос, вы не сможете проверить, действительно ли он все еще действителен. Здесь происходит то, что в случае сбоя вы вызываете loginWithPublishPermissions (по сути, запрос на дополнительные разрешения, когда у вас уже есть токен), это не удается, потому что пользователь удалил приложение. Во второй раз (успешный случай) вы вызываете loginWithRead, и это рассматривается как совершенно новый запрос на аутентификацию, который завершается успешно.   -  person Ming Li    schedule 27.04.2015


Ответы (2)


Просто сделайте что-то вроде:

@Override
public void onError(FacebookException error) {
    Timber.e(error, "Error during facebook login");
    AccessToken.setCurrentAccessToken(null);
    LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("email"))
}
person Divers    schedule 01.03.2016
comment
Извините за поздний ответ: я хочу настроить это сообщение. drive.google.com/open?id=0B7xjlHVL47MbWVVKY1JSbWJGdk0 - person K.Sopheak; 08.12.2016
comment
Вы не можете настроить это сообщение - person Divers; 08.12.2016
comment
Итак, мы не можем скрыть это и использовать вместо этого другое сообщение? - person K.Sopheak; 08.12.2016
comment
Вы можете - переключить приложение из режима разработки в производство. - person Divers; 08.12.2016

Звонок AccessToken.refreshCurrentAccessTokenAsync() помог мне. Я получаю ошибку в реализации FacebookCallback.onError(), где я вызываю AccessToken.refreshCurrentAccessTokenAsync(), который очищает токен доступа в Facebook SDK.

Поскольку это асинхронный вызов, я не могу немедленно вызвать loginManager.logInWithReadPermissions(); Обратного вызова нет, поэтому я показываю пользователю AlertDialog, и когда пользователь нажимает «ОК», я вызываю loginManager.logInWithReadPermissions().

Таким образом, пользовательский опыт не так уж плох и приемлем для крайнего случая.

person bentobox    schedule 06.07.2015