5

I am developing an Android app that integrates with facebook. The app works perfectly fine when I set LoginButton.setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO).

The problem arises when I try to use SSO. I get the error below. I used to get a similar error when I used an incorrect keyhash; this is not the case anymore because the Webview log in works fine. What is event more surprising is that the Android app works if the app is installed in FB. For example, I am the app manager therefore it gets installed in my facebook profile by default, but when I try with another fb account that doesn't have the app installed it doesn't work. When I attempt to log in the error below appears and I get a dialog telling me that basic permissions will be granted, but in reality I do not even get basic permissions.

I have submitted the app for review in order to get it shown on the App Center. When I do that, the dialog shows a checkbox where I acknowledge that my app uses SSO. Does facebook need to approve my app before I can use SSO (if so, this doesn't make sense)

I have spent hours trying to solve this, and I can't find the solution. Please help.

08-24 01:39:16.058: W/Bundle(21880): Key com.facebook.platform.protocol.PROTOCOL_VERSION expected String but value was a java.lang.Integer.  The default value <null> was returned.
08-24 01:39:16.068: W/Bundle(21880): Attempt to cast generated internal exception:
08-24 01:39:16.068: W/Bundle(21880): java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
08-24 01:39:16.068: W/Bundle(21880):    at android.os.Bundle.getString(Bundle.java:1069)
08-24 01:39:16.068: W/Bundle(21880):    at android.content.Intent.getStringExtra(Intent.java:4350)
08-24 01:39:16.068: W/Bundle(21880):    at com.facebook.AuthorizationClient$KatanaLoginDialogAuthHandler.tryAuthorize(AuthorizationClient.java:821)
08-24 01:39:16.068: W/Bundle(21880):    at com.facebook.AuthorizationClient.tryCurrentHandler(AuthorizationClient.java:272)
08-24 01:39:16.068: W/Bundle(21880):    at com.facebook.AuthorizationClient.tryNextHandler(AuthorizationClient.java:238)
08-24 01:39:16.068: W/Bundle(21880):    at com.facebook.AuthorizationClient$GetTokenAuthHandler.getTokenCompleted(AuthorizationClient.java:772)
08-24 01:39:16.068: W/Bundle(21880):    at com.facebook.AuthorizationClient$GetTokenAuthHandler$1.completed(AuthorizationClient.java:731)
08-24 01:39:16.068: W/Bundle(21880):    at com.facebook.internal.PlatformServiceClient.callback(PlatformServiceClient.java:144)
08-24 01:39:16.068: W/Bundle(21880):    at com.facebook.internal.PlatformServiceClient.handleMessage(PlatformServiceClient.java:128)
08-24 01:39:16.068: W/Bundle(21880):    at com.facebook.internal.PlatformServiceClient$1.handleMessage(PlatformServiceClient.java:54)
08-24 01:39:16.068: W/Bundle(21880):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-24 01:39:16.068: W/Bundle(21880):    at android.os.Looper.loop(Looper.java:137)
08-24 01:39:16.068: W/Bundle(21880):    at android.app.ActivityThread.main(ActivityThread.java:5227)
08-24 01:39:16.068: W/Bundle(21880):    at java.lang.reflect.Method.invokeNative(Native Method)
08-24 01:39:16.068: W/Bundle(21880):    at java.lang.reflect.Method.invoke(Method.java:511)
08-24 01:39:16.068: W/Bundle(21880):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
08-24 01:39:16.068: W/Bundle(21880):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
08-24 01:39:16.068: W/Bundle(21880):    at dalvik.system.NativeStart.main(Native Method)
Emmanuel
  • 12,564
  • 4
  • 35
  • 50
  • While the ClassCastException certainly isn't good, I don't think it's the cause of your issues. Can you see if there are any exceptions passed back in your Session.StatusCallback? – Ming Li Aug 26 '13 at 22:03
  • The ClassCastException is thrown by the Facebook SDK because there is some call that should return a String (maybe some Auth key) when the app connects correctly, and not an Integer. – Emmanuel Aug 26 '13 at 22:34
  • I understand that, but it's also not causing actual log in issues with the sample apps, or a whole host of other people who are now on 3.5, so my hypothesis is that there are other issues causing your app not being able to log in. Can you please check if there are any exceptions passed to your StatusCallback? – Ming Li Aug 27 '13 at 19:55
  • I will check and get back at you. – Emmanuel Aug 28 '13 at 14:56

5 Answers5

16

I had a similar logcat output and found out that it was related to incorrectness in the FB 3.5 source code. As described above it´s on line 821 in AuthorizationClient.java. There should be getIntExtra instead of getStringExtra. Download the source from github and change

intent.getStringExtra(NativeProtocol.EXTRA_PROTOCOL_VERSION));

to

""+intent.getIntExtra(NativeProtocol.EXTRA_PROTOCOL_VERSION, 0));
hakanostrom
  • 983
  • 7
  • 14
3

Problem is hashkey is wong

For Linux

Open Terminal :

For Debug Build

keytool -exportcert -alias androiddebugkey -keystore debug.keystore | openssl sha1 -binary | openssl base64

you wil find debug.keystore from ".android" folder copy it from and paste on desktop and run above command

For release Build

keytool -exportcert -alias <aliasName> -keystore <keystoreFilePath> | openssl sha1 -binary | openssl base64

NOTE : Make sure In Both case it must ask for password. If it does not asks for password that means something is wrong in command.

Biraj Zalavadia
  • 27,124
  • 9
  • 56
  • 73
  • The hashkey is correct. The method you are suggesting not always works. It is better to do it via code or by copying it to .txt files in several steps like it is done here http://stackoverflow.com/questions/5306009/facebook-android-generate-key-hash/12405323#12405323 – Emmanuel Aug 24 '13 at 07:16
3

Ok, here is what was happening. On my onCreate() I was passing "create_event" and "publish_actions" permissions to my LoginButton. I went ahead and set an onErrorListener on the LoginButton and I was getting this:

08-28 14:06:01.679: E/FACEBOOK LOGIN ERROR(28293): UnknownError: The app must ask for a basic_info permission at install time.

As it turns out, upon install, your app HAS to request read permissions first, and once you are logged in you could ask for publish permissions. Here is how facebook explains it (under Publishing Permissions):

Apps should separate the request of read and publish permissions. Plan your app around requesting the bare minimum of read permissions at initial login and then any publish permissions when a person actually needs them, for example when they want to create an Open Graph story from within the app. This provides the best user experience and optimizes conversion.

You may receive Developer Alerts if your app requests read and publish permissions back-to-back. To stop receiving these alerts, separate your requests or follow the guidelines below for exceptional cases.

In the rare case your app requires publishing permissions up front (for example, an app that does nothing but publish a user's mood to Facebook), first request the bare minimum read permissions at initial login. After the user logs in with Facebook, show the user a screen explaining why your app needs publishing permissions and let the user opt-in to the publishing permission request by clicking a button. This will provide the user more context and improve your conversion.

Another legitimate case for requesting read and publish permissions back-to-back is for users that log in to your app with email or a non-Facebook login option. When these users want to publish to Facebook, your app will need to request read permissions to connect their account followed by publishing permissions back-to-back. In this case, make sure that the only read permissions you request are public profile and friend list. This provides the best user experience because the user wants to simply publish from your app and is not interested in providing additional read permissions. It will also improve your conversion.

To solve my problem, I just didn't request any permissions on start-up (you get the "basic_info" read permission by default), and then I used

 helper = new UiLifecycleHelper(this, new StatusCallback() {

            @Override
            public void call(Session session, SessionState state, Exception exception) {
                // TODO Auto-generated method stub
                if(state.isOpened()&&!session.getPermissions().contains("publish_actions"))
                    session.requestNewPublishPermissions(new NewPermissionsRequest(SplashScreen.this, "publish_actions"));

            }
        });

in onCreate(). Since call() gets called anytime there is a change in the Session, the session.isOpen() will be true, if we do not check if the permission is set, we will enter in an infinite loop.

Apparently, the warning above had nothing to do with the actual error. Just as a suggestion, people that have problems like this, set the onErrorListener and Log it.

Log.e("FACEBOOK LOGIN ERROR", error.getLocalizedMessage());
Emmanuel
  • 12,564
  • 4
  • 35
  • 50
0

I'm not sure if this is helpful, but it may be related to the new SDK release. Are you using the Android Facebook SDK v3.5? Maybe try using an earlier version of the SDK, 3.0.2, you can find it browsing their github repository.

Edit:

I've fixed the problem in my case but can't say I know what the actual problem is:

  • Check your hash and app_id, make sure you add your hash key to your application on the developer website, instead of the samples application.

  • Make sure your Manifest includes this activity exactly as specified / appears in the samples

    activity android:name="com.facebook.LoginActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar"
    android:label="@string/app_name"

  • Make sure you add the meta-data within the < application> tag of your Manifest

    meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/app_id"

  • Make sure that on your Facebook developers account, the application you're deploying specifies the correct package and main class name

  • I also removed the following attributes from my main login activity in the manifest:

    android:exported="true" android:noHistory="true"

This is what I did and it seems to work for now, I can't say if this is a universal fix but at least it's worth checking that all those are correct.

hbot
  • 644
  • 7
  • 17
  • I am using 3.5. I think it was not working in 3.0.2 as well. I will give it a try. – Emmanuel Aug 24 '13 at 22:06
  • Yeah, I'm having the same problem, don't really know which avenues to pursue to find a fix. I use two separate machines to deploy the app I'm working on. The curious thing is that from one machine it works (I don't get the warnings) whereas from the other it doesn't, and the the app crashes. I think it's a problem with the certificates/signatures/hash key. – hbot Aug 26 '13 at 21:09
  • Any luck finding a solution to this? – hbot Aug 27 '13 at 14:30
  • Did my answer help you? – Emmanuel Aug 28 '13 at 21:07
0

The fact that login via WebView works doesn't mean that the hashkey is correct, since it works even if there's no hashkey in the Facebook app settings. So double check your hashkey.

Besides since you say that it works only with your profile and not with others, check you correctly added them as testers, or that you're not in Sandbox mode.

novembre
  • 429
  • 4
  • 8
  • I will re-check the hashkey, and let you know. I am not in Sandbox mode. The reason why only I have no problem when I log in is because the app gets already added to by facebook profile when I create it. Sicne the app doesn't seem to authenticate, I doensn't install the app to the user's facebook... – Emmanuel Aug 28 '13 at 15:00