現象
Facebookログイン時にFacebookCallbackのonSuccessが呼ばれ、AccessTokenが取得できているにも関わらず、Profile.getCurrentProfile()がnullになるケースがあった。
FacebookCallback<LoginResult> mFacebookCallback =
new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
Profile profile = Profile.getCurrentProfile(); //null !!
}
};
原因
Profile情報はログイン後にProfile.fetchProfileForCurrentAccessToken()によって非同期に再取得されるため、同期のタイミングによっては値の更新が間に合わない。
//LoginManager.finishLogin()を一部抜粋
private void finishLogin()
if (newToken != null) {
AccessToken.setCurrentAccessToken(newToken);
Profile.fetchProfileForCurrentAccessToken(); //ここでProfileの更新を行う。
}
public static void fetchProfileForCurrentAccessToken() {
AccessToken accessToken = AccessToken.getCurrentAccessToken();
if (accessToken == null) {
Profile.setCurrentProfile(null);
return;
}
Utility.getGraphMeRequestWithCacheAsync(accessToken.getToken(),
new Utility.GraphMeRequestWithCacheCallback() {
@Override
public void onSuccess(JSONObject userInfo) {
String id = userInfo.optString("id");
if (id == null) {
return;
}
String link = userInfo.optString("link");
Profile profile = new Profile(
id,
userInfo.optString("first_name"),
userInfo.optString("middle_name"),
userInfo.optString("last_name"),
userInfo.optString("name"),
link != null ? Uri.parse(link) : null
);
Profile.setCurrentProfile(profile);
}
@Override
public void onFailure(FacebookException error) {
return;
}
});
}
対策
Looperなどで取得できるまで待つか、ProfileTrackerなどを使ってイベントをハンドリングするのが良さそう。