現象
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などを使ってイベントをハンドリングするのが良さそう。