I'm trying to be able to log into Facebook by following the Facebook Getting Started Guide. However a session.isOpened() call always returns false, if the Facebook App is also installed on my phone. If it is not installed on my phone everything work fine. My code is as follows:
public static void loginToFacebook(final Activity activity) {
Log.d("Hello", Global.debug + " Login to Facebook");
Session.openActiveSession(activity, true, new Session.StatusCallback() {
// callback when session changes state
#Override
public void call(Session session, SessionState state, Exception exception) {
Log.d("Session Changed", Global.debug);
if (session.isOpened()) {
Log.d("Session Is Opened", Global.debug);
Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
Log.d("Request Completed", Global.debug);
if (user != null) {
Log.d("Hello ", Global.debug + " " + user.getName() + "!");
}
}
});
}
}
});
}
Session Changed is printed to the log, but Session Is Opened never is, until I delete the Facebook app, then it prints the name associated with my Facebook account like it's supposed to after I log in. I've looked around and found that others with the same problem were using the wrong Key Hash, and found the right one by using:
try {
PackageInfo info = getPackageManager().getPackageInfo("com.facebook.login", PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.d("KeyHash:", Global.debug + " " + Base64.encodeToString(md.digest(), Base64.DEFAULT));
}
} catch (NameNotFoundException e) {
Log.d("Name Not Found", Global.debug);
} catch (NoSuchAlgorithmException e) {
Log.d("No Such Algorithm", Global.debug);
}
But that printed the same Key Hash that I was already using. Is there something that I'm doing wrong? Any help would be greatly appreciated, thank you!
Related
I know how to login:
ParseTwitterUtils.logIn(loginView.getCurrentContext(), new LogInCallback() {
#Override
public void done(ParseUser parseUser, ParseException e) {
if (e == null) {
String welcomeMessage = "";
if (parseUser.isNew()) {
welcomeMessage = "Hello new guy!";
} else {
welcomeMessage = "Welcome back!";
}
loginView.showLoginSuccess(parseUser, welcomeMessage);
} else {
String errorMessage = "Seems we have a problem : " + e.getLocalizedMessage();
loginView.showLoginFail(errorMessage);
}
}
});
And to logout :
ParseUser.logOutInBackground(new LogOutCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
homeView.goLogin(true, "See you soon");
} else {
homeView.goLogin(false, "Error detected : " + e.getLocalizedMessage());
}
}
});
But when I want to log in again, I don't have the alert dialog asking me to choose accounts (i use the webview since Twitter app is not installed on the emulator).
How to truly logout from Parse using Twitter login?
In iOS, you can revise the source code of Parse in PFOauth1FlowDialog.m
- (void)loadURL:(NSURL *)url queryParameters:(NSDictionary *)parameters {
NSMutableDictionary *_parameter = [[NSMutableDictionary alloc] init];
[_parameter setObject:#"true" forKey:#"force_login"];
[_parameter addEntriesFromDictionary:parameters];
_loadingURL = [[self class] _urlFromBaseURL:url queryParameters:_parameter];
NSURLRequest *request = [NSURLRequest requestWithURL:_loadingURL];
[_webView loadRequest:request];
}
Then everything should work fine, And this should also work in Android.
Use the unlink functions from ParseTwitterUtils:
https://parse.com/docs/android/api/com/parse/ParseTwitterUtils.html#unlink(com.parse.ParseUser)
This will remove the link between the twitter account and the parse user.
The confusion seems to stem from the fact that the api is so straightforward.
What you're doing in the login is associating a twitter account with a parse user and logging in as that parse user. Then when you are logging out, you are only logging out of the parse user, and the twitter account is still linked to the parse user. Therefore when you go to log in again it automatically uses the twitter account to log in as the parse user.
I'v tried a lot of solutions to implement Facebook login based on the Parse SDK without success.
It seems like I'm missing something.
Generating Facebook hash
I tried to generate the hash with this command (and many others) and password = android:
keytool -exportcert -alias androiddebugkey -keystore C:\Users\Ido\.android\debug.keystore | openssl sha1 -binary | openssl base64
But it didn't work for me, every time I tried to login I got an error that the hash key is not authorized.
Putting this code in the Appliction OnCreate made the work for me (I didn't get the error anymore):
try {
PackageInfo info = getPackageManager().getPackageInfo("com.idob.soccertimer", PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
String sign= Base64.encodeToString(md.digest(), Base64.DEFAULT);
Log.e("MY KEY HASH:", sign);
Toast.makeText(getApplicationContext(), sign, Toast.LENGTH_LONG).show();
}
} catch (PackageManager.NameNotFoundException e) {
} catch (NoSuchAlgorithmException e) {
}
Application implementation
I made the adjustments for the Facebook and Parse:
Initialize in the onCreate of the Application:
ParseFacebookUtils.initialize(getString(R.string.facebook_app_id));
Overriding the onActivityResult method in my loginFragment:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
ParseFacebookUtils.finishAuthentication(requestCode, resultCode, data);
}
Add meta tag:
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id"/>
I use this code to login:
ParseFacebookUtils.logIn(getActivity(), new LogInCallback() {
#Override
public void done(ParseUser user, ParseException err) {
if (user != null) {
Log.e("MyApp", err.getMessage());
}
if (user == null) {
Log.d("MyApp", "Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew()) {
Log.d("MyApp", "User signed up and logged in through Facebook!");
} else {
Log.d("MyApp", "User logged in through Facebook!");
}
}
});
My problem is that the LogInCallback don't call, when I try to login twice - one LogInCallback is returned with user = null and err = null
The OnActivityResult is not called at all.
This path looks wrong to me :
C:\Users\Ido. android\debug.keystore
I'm a linux user and can't be 100% sure on windows paths, but I'm pretty sure it should be located :
C:\Documents and Settings\[User Name]\.android\debug.keystore
or
C:\Users\[User Name]\.android\debug.keystore
The fragment's onActivityResults would not call automatically, it should be called by the activity's onActivityResult
I know that's a question answered before, but no one seems to work and i spend a week on int.
I tried to get my Key Hash from key tool and put them on Facebook app Key hashes, release and debug. No one worked.
"(404) Key hash xxxxxxxxxxxx does not match any storeed key hashes"
That's rare, my keys are different.
So i tried:
PackageInfo info = getPackageManager().getPackageInfo(
"com.pakage.example",
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
String result = Base64.encodeToString(md.digest(), Base64.DEFAULT);
Toast.makeText(MainActivity.this , result + result.toUpperCase(), Toast.LENGTH_LONG).show();
}
That return me the same Key Has request by Facebook (xxxxxxxxxxxx), so i added them to Facebook App, but Facebook return me "(404) Key hash xxxxxxxxxxxx does not match any storeed key hashes".
When i removed Facebook App from my device, i was avaliebe to share status via WebDialog.
My final code seems to:
if (FacebookDialog.canPresentShareDialog(parent, FacebookDialog.ShareDialogFeature.SHARE_DIALOG))
{
publishFacebookDialog(points); //FacebookDialog
}
else
{
Session session = Session.getActiveSession();
if (session != null && session.isOpened()) {
publishFeedDialog(points); //WebDialog
}
else
{
Intent intent = new Intent(parent, LoginUsingCustomFragmentActivity.class); //From FacebookSDK demo
parent.startActivityForResult(intent, 666);
}
}
PublishFacebookDialog function:
private void publishFacebookDialog(String puntuacion) {
FacebookDialog shareDialog = new FacebookDialog.ShareDialogBuilder(parent)
.setLink("bla")
.setCaption("bla")
.setName("bla")
.build();
uiHelper.trackPendingDialogCall(shareDialog.present());
}
PublishFeedDialog function:
private void publishFeedDialog(String puntuacion) {
Bundle params = new Bundle();
params.putString("name", "bla");
params.putString("caption", "bla");
params.putString("link", "bla");
WebDialog feedDialog = ( new WebDialog.FeedDialogBuilder(parent,Session.getActiveSession(),params))
.setOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(Bundle values, FacebookException error) {
if (error == null) {
final String postId = values.getString("post_id");
if (postId != null) {
} else {
}
} else if (error instanceof FacebookOperationCanceledException) {
// User clicked the "x" button
} else {
// Generic, ex: network error
}
}
})
.build();
feedDialog.show();
}
The LoginUsingCustomFragmentActivity class is the same that FacebookSDK
Tried:
Remove app from facebook and re add.
Replace symbols like /_+ etc, like from other answered posts.
Use the same key hash reported by "(404) Key hash xxxxxxxxxxxx does not ...." on Facebook App.
Any idea?
Lot of thanks.
I was facing the same problem, the hash code that i generated through openssl was wrong i then used this function and it help. Hope it help you all too.
private void printKeyHash() {
// Add code to print out the key hash
try {
PackageInfo info = getPackageManager().getPackageInfo("YOUR PACKAGE NAME", PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
}
} catch (NameNotFoundException e) {
Log.e("KeyHash:", e.toString());
} catch (NoSuchAlgorithmException e) {
Log.e("KeyHash:", e.toString());
}
}
Use the hash code that is printed in logs and enjoy. Happy Coding :)
See my answer here, there are couple of things to be aware of when adding your hashkey :
https://stackoverflow.com/a/27290250/1495261
I am working on android Application. when facebook native application installed it does not work and show only two popup. but if itis not installed it redirect to facebook website and works fine .How i can resolve this . any help will be appreciated. I have checked and added all hashkey in facebook app. but still not working .
statusCallback = new SessionStatusCallback();
Session session = Session.getActiveSession();
this.isLogin = isLoginUser;
session = null;
if (session == null) {
if (savedInstanceState != null) {
session = Session.restoreSession(context, null, statusCallback,savedInstanceState);
}
if (session == null) {
session = new Session.Builder(context).setApplicationId(
"688998947797106").build();
}
Session.setActiveSession(session);
if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED)) {
session.openForRead(new Session.OpenRequest(activity)
.setCallback(statusCallback)
.setLoginBehavior(
SessionLoginBehavior.SSO_WITH_FALLBACK)
.setPermissions(Arrays.asList("email")));
}
}
if (!session.isOpened() && !session.isClosed()) {
session.openForRead(new Session.OpenRequest(activity)
.setCallback(statusCallback)
.setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK)
.setPermissions(Arrays.asList("email")));
} else {
Session.openActiveSession(activity, true, statusCallback);
}
I also Had same problem, I have added different key. See my Question Here
You will get more Information on this discussion Click here See The answer given By Abhishek Agrawal in that Link.
Add following code to your Activities onCreate and check which hashkey is sent by your app to facebook,
PackageInfo info;
try {
info = getPackageManager().getPackageInfo("com.example.yourpackagename", PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md;
md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
String something = new String(Base64.encode(md.digest(), 0));
//String something = new String(Base64.encodeBytes(md.digest()));
Log.e("hash key", something);
}
} catch (NameNotFoundException e1) {
Log.e("name not found", e1.toString());
} catch (NoSuchAlgorithmException e) {
Log.e("no such an algorithm", e.toString());
} catch (Exception e) {
Log.e("exception", e.toString());
}
First Check your hash key with these lines of code given by me at this link Facebook Integration in Android Application and if it is not working yet then please check that your Facebook Android Application in mobile is updated. If the application is not updated update your Facebook application and try to post.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
facebook.authorizeCallback(requestCode, resultCode, data);
}
Use this code in the activity where you call facebook login request.
I want to sign in to my app with Facebook, but I get next message to my Logcat:
Failed to find provider info for com.facebook.katana.provider.PlatformProvider
and launcher does not loading. I get my hash key like this.
My code is:
case R.id.btn_start_facebook:
// callback when session changes state
// start Facebook Login
Session.openActiveSession(this, true, new Session.StatusCallback() {
// callback when session changes state
#Override
public void call(Session session, SessionState state,
Exception exception) {
if (session.isOpened()) {
// make request to the /me API
Request.executeMeRequestAsync(session,
new Request.GraphUserCallback() {
// callback after Graph API response
// with user object
#Override
public void onCompleted(GraphUser user,
Response response) {
if (user != null) {
Log.d("myDebug",
"Hello " + user.getName()
+ " user id = "
+ user.getId()
+ "!");
} else {
Log.d("myDebug", "User is null");
}
}
});
}
}
});
add permission of internet in menifest of your application
<uses-permission android:name="android.permission.INTERNET"/>
The issue for me was that that facebook app installed on Android was outdated and not consistent with my Facebook Android SDK.
Please look at this page: Developer Facebook and be sure that that the Facebook SDK is consistent with the Facebook app that installed on your Android.
Maybe you can try to do more error checking like this
if (user != null) {
Log.d("myDebug",
"Hello " + user.getName()
+ " user id = "
+ user.getId()
+ "!");
} else {
Log.d("myDebug", "User is null");
FacebookRequestError error = response.getError();
if (error != null) {
Log.d(String.format("Error: %s", error.getErrorMessage()));
}
}
If somebody has that same error and the answers above did not work check if you move your facebook app to SD card. When you connect your smartphone to the pc it automatically disable every apps located at SD card.
The solution that I found was move the Facebook app to the phone again to test.
You could also disconnect the smartphone and run the application and it works fine, but you will not have access to debug etc.