ParseFacebookUtils を使用して、Android アプリに Parse & Facebook フローを実装しました。
TL;DR
- Facebook でログイン (およびリンク) した後、Parse ユーザーを作成しました (ParseFacebookUtils.logIn)
- ログアウトしました (ParseFacebookUtils.logOut & ParseUser.logOut)
- Facebook で再度ログインすると、古い Parse ユーザーをフェッチする代わりに、新しい Parse ユーザーが作成されます。
より長いバージョン: ログイン フローが機能します。ParseFacebookUtils.logIn 呼び出しによって Facebook ダイアログが起動され、新しい Parse ユーザーが作成され、ユーザーの Facebook アカウントにリンクされます。
この問題は、ログアウト (ParseFacebookUtils.logOut および ParseUser.logOut) し、同じ Parse ユーザーに再度ログインしようとした後に発生します。Facebook ダイアログが短時間表示された後、アプリにリダイレクトされます (その Facebook ユーザーに対して既に承認されているため) が、関連する Facebook ユーザーの前のユーザーを見つける代わりに、新しい Parse ユーザーが作成されているようです。
質問: このようなフローを有効にする方法はありますか? 作成済みのユーザーを手動で取得する必要がありますか?
すべてのログイン ロジックが存在するMainActivityのコード:
public class MainActivity extends Activity {
private ProgressBar progressBar;
private Button loginButton;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = (ProgressBar) findViewById(R.id.splash_loading_spinner);
loginButton = (Button) findViewById(R.id.splash_facebook_login);
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onLoginButtonClicked();
}
});
ParseAnalytics.trackAppOpened(getIntent());
// Check if there is a currently logged in user
// and they are linked to a Facebook account.
ParseUser currentUser = ParseUser.getCurrentUser();
if ((currentUser != null) && ParseFacebookUtils.isLinked(currentUser)) {
// load data from Parse user and launch the next activity immediately
retrieveData();
} else {
failedLoggingIn();
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
ParseFacebookUtils.getSession().onActivityResult(this, requestCode, resultCode, data);
}
// this method will link the current ParseUser to the used Facebook account if needed
private boolean linkFacebookUser() {
ParseUser user = ParseUser.getCurrentUser();
// save fb_id and email to the parse user
Request.newMeRequest(ParseFacebookUtils.getSession(), new Request.GraphUserCallback() {
@Override
public void onCompleted(GraphUser fbUser, Response response) {
if (fbUser == null) {
Log.e("Facebook Me Request", "Failed fetching user Facebook Graph object.");
} else {
Log.d("Facebook Me Request", "Received Facebook graph object for "+fbUser.getId()+"("+fbUser.getProperty("email").toString()+")");
ParseUser.getCurrentUser().put("fb_id", fbUser.getId());
ParseUser.getCurrentUser().setEmail(fbUser.getProperty("email").toString());
ParseUser.getCurrentUser().setUsername(fbUser.getProperty("email").toString());
ParseUser.getCurrentUser().setPassword(UUID.randomUUID().toString());
ParseUser.getCurrentUser().signUpInBackground(new SignUpCallback() {
@Override
public void done(ParseException e) {
if (e == null) {
Log.d("Parse signup user", "Successfully saved a new Parse-Facebook user!");
retrieveData();
} else {
Log.e("Parse signup user", "FAILED saving a new Parse-Facebook user. Error: " + e.getMessage());
e.printStackTrace();
}
}
});
}
}
}).executeAsync();
return true;
}
private void retrieveData() {
// fetch data needed to show movie recommendations
Log.d("Parse Facebook Login Info", "fb_id=" + ParseUser.getCurrentUser().get("fb_id"));
startActivity(new Intent(this, BrowseMoviesActivity.class));
finish();
}
private void failedLoggingIn() {
ParseUser.logOut();
progressBar.setVisibility(View.GONE);
loginButton.setVisibility(View.VISIBLE);
}
private void onLoginButtonClicked() {
Log.d("UI", "Clicked the Facebook login button");
progressBar.setVisibility(View.VISIBLE);
loginButton.setVisibility(View.GONE);
List<String> permissions = Arrays.asList(
"public_profile",
"user_friends",
"user_actions.video",
ParseFacebookUtils.Permissions.User.EMAIL,
ParseFacebookUtils.Permissions.User.ABOUT_ME,
ParseFacebookUtils.Permissions.User.RELATIONSHIPS,
ParseFacebookUtils.Permissions.User.BIRTHDAY,
ParseFacebookUtils.Permissions.User.LOCATION
);
ParseFacebookUtils.logIn(permissions, this, new LogInCallback() {
@Override
public void done(ParseUser user, ParseException err) {
MainActivity.this.progressBar.setVisibility(View.GONE);
if (user == null) {
Log.d("ParseFacebookLogin", "Uh oh. The user cancelled the Facebook login.");
if (err != null) {
Log.d("ParseFacebookLogin", "Error: " + err.getLocalizedMessage());
}
failedLoggingIn();
} else if (user.isNew()) {
Log.d("ParseFacebookLogin", "User signed up and logged in through Facebook!");
// we should probably use this scenario to set fb id to the Parse user
linkFacebookUser();
} else {
Log.d("ParseFacebookLogin", "User logged in through Facebook!");
if (user.get("fb_id") == null) {
linkFacebookUser();
} else {
retrieveData();
}
}
}
});
}
}