Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Facebook Login Flow on Android Broken Since Daily Build 1141
Started by aukStudios Jul 19 2013 02:22 PM

21 replies to this topic
android facebook login bug regression
[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

aukStudios

[GLOBAL: userInfoPane.html]
aukStudios
  • Corona Geek

  • 1,003 posts
  • Corona SDK

Daily Build 1141 broke the Facebook login flow for Android.  The changelog for that build lists "Android: Update the Facebook SDK to version 3.0.1", so that's the culprit.

 

Specifically, prior to build 1141 (e.g., build 1139), facebook.login() would present the standard Facebook interface to request user permissions.  Starting in build 1141, it presents an ugly native alert to request user permissions.  The alert doesn't allow the user to change the privacy settings of the permissions, looks untrustworthy, and may be indicative of more serious issues with how the login flow is being handled.

 

EDIT: Per additional note further down this thread, it's possible that this change in behavior isn't actually a bug, but it would still be interesting to understand why it changed.

 

The bug was first mentioned in a previous thread (http://forums.coronalabs.com/topic/36635-android-facebook-after-build-coronasdk-20131076/), but the conversation on that thread changed topic, and the original core issue hasn't been addressed.

 

Here's information about my device setup and an extremely simple test case that demonstrates the issue:

- DroidX running Android 2.2.  (I haven't tested on higher Android OS versions; it may or may not affect them too)

- Device must have the latest Facebook app installed on the device (I updated it from Google Play today)

- You must not have your app already authorized on Facebook, because if you do, you won't see the login/permission interface.  (To deauthorize an app on Facebook, go to Account Settings, select Apps from the left column, and then click the 'x' next to the app name.)

 

main.lua

local facebook = require("facebook")
local widget = require("widget")
 
local appId = "YOUR APP ID HERE"
 
local listener = function(event)
    for k,v in pairs(event) do
        print(k,v)
    end
end
 
local login = function()
    facebook.login(appId, listener, {"user_likes"})
end
 
local loginButton = widget.newButton(
        {
            label = "Login",
            onRelease = login
        }
    )
loginButton.x, loginButton.y = 100,100

 

build.settings

settings = 
{
    android =
    {
        usesPermissions =
        {
            "android.permission.INTERNET",
            "android.permission.ACCESS_WIFI_STATE",
            "android.permission.ACCESS_NETWORK_STATE",
            "android.permission.READ_PHONE_STATE",
        },
    }
}

 

I'll also file a bug report for this, but I wanted to post it here in the hopes that it'll get more immediate attention.

 

Thanks.

 

- Andrew



[TOPIC: post.html]
#2

aukStudios

[GLOBAL: userInfoPane.html]
aukStudios
  • Corona Geek

  • 1,003 posts
  • Corona SDK

I've submitted this as a bug report, case 25037.

 

Thanks.

 

- Andrew



[TOPIC: post.html]
#3

aukStudios

[GLOBAL: userInfoPane.html]
aukStudios
  • Corona Geek

  • 1,003 posts
  • Corona SDK

A further observation.  Facebook's documentation about the Android login flow (https://developers.facebook.com/docs/facebook-login/overview/ and https://developers.facebook.com/docs/tutorials/androidsdk/3.0/scrumptious/authenticate/) does show a native alert being used to grant permissions.  So maybe the behavior in Build 1141 isn't a bug after all, though it's still strange why it would have changed from 1139.

 

- Andrew



[TOPIC: post.html]
#4

beckslash

[GLOBAL: userInfoPane.html]
beckslash
  • Contributor

  • 113 posts
  • Corona SDK

I had this problem too. Needed a few days to figure it out without being able to find out much.

 

I posted what happens with facebook after 3.0.1 and how to fix it: http://forums.coronalabs.com/topic/37173-resolved-facebook-key-hashes-no-longer-required-for-android/

 

Hope it helps.



[TOPIC: post.html]
#5

aukStudios

[GLOBAL: userInfoPane.html]
aukStudios
  • Corona Geek

  • 1,003 posts
  • Corona SDK

Thanks, I'll take a look.



[TOPIC: post.html]
#6

aukStudios

[GLOBAL: userInfoPane.html]
aukStudios
  • Corona Geek

  • 1,003 posts
  • Corona SDK

Yup, that enabled me to resolve it.  So the short answer to anyone reading this thread is:

- When moving from Build 1139 to 1141 on Android, I believe Corona switched from a native WebView Facebook login flow to the Facebook Android SDK.  As a result, the login flow appears using native alerts.  It's a change in behavior for sure, but I don't think it's a bug

- Previously, you could request any permissions you wanted in your initial login.  Now, the Facebook Android SDK requires that the initial login request only read permissions (such as "basic_info").  You can't request a write permission (such as "publish_actions") before your app has been granted a read permission.  So if the user has never logged in before, @beckslah offers a solution if the first facebook request needs a write permission.  You have to call facebook.login() twice, first for just a read permission, and then again for the write permission



[TOPIC: post.html]
#7

Naomi

[GLOBAL: userInfoPane.html]
Naomi
  • Corona Geek

  • 2,303 posts
  • Enterprise

Hey, Andrew @aukStudios and @beckslah, I'm not sure if I'm following the issues and solution you're discussing.  

 

For my facebook.login request, I do include "publish_actions" permission.  And I see that, with Android, yes, the first time the app is ever launched by the user, and when user triggers FB login the very first time, the initial login process go through three screens -- first one requires the user to enter username & password, second one lets the user know what user info my app wants to access, then the third one that lets the user change the privacy setting as it relates to my app.  

 

Once the user authorizes my app, the next time user does anything FB related, it simply does what it should (such as posting scores, retrieving friends' scores, etc.) without going though login screens ever again.

 

Is the initial 3-step login process the issue that is being addressed by logging in without "publish_actions", logging out, and then logging back in again with "publish_actions"...?

 

Naomi



[TOPIC: post.html]
#8

beckslash

[GLOBAL: userInfoPane.html]
beckslash
  • Contributor

  • 113 posts
  • Corona SDK

If it asks user to enter username and password that means everything happens "inside" your app. The problem only appears when the user is redirected to the native Facebook app.

 

On Samsung Galaxy S3 this is now handled via a native alert. In this case the flow had to be like I mentioned before.



[TOPIC: post.html]
#9

Naomi

[GLOBAL: userInfoPane.html]
Naomi
  • Corona Geek

  • 2,303 posts
  • Enterprise

Thank you, @beckslah.  So, the issue happens only if the Android device has already installed some native Facebook app?  

 

I tried my app on Samsung Galaxy S3, and the FB login process turned out to be identical to the 3-step login process I posted above.  And that's not a problem, right?  To reproduce the issue, I'd need to install some native Facebook app first, then try again?  

 

And... how do we detect if the device will have a problem so that we'd want to call facebook.logout first?  Hmmm...  set a flag that tells my app if this is the first time the user is logging in to FB via my app, and in such case, logout first, then do the normal login process?  Perhaps that's the best, you think?

 

Naomi

 

Edit:  Ah, one more thing, my Samsung Galaxy S3 has Android version 4.1.2 on it.  Is this why I don't see the issue?  If this is OS version issue, maybe I should just retrieve device info and if it's Android version 2.2 (or maybe earlier even), I may just add the facebook.logout before calling facebook.login?



[TOPIC: post.html]
#10

aukStudios

[GLOBAL: userInfoPane.html]
aukStudios
  • Corona Geek

  • 1,003 posts
  • Corona SDK

Hi Naomi, I don't know which Android OS versions have the issue, but here's what I experienced. I used Android 2.2, with the Facebook app already installed on the device and the user logged in. If in my own app I call facebook.login() for the first time requesting a write permission such as publish_actions, it'll fail. Trying again will still fail. The only solution seems to be having the first call to facebook.login() ask for a read permission, and once it succeeds, only then asking for a write permission. I don't know if this is necessary on Android versions above 2.2, or on devices where the Facebook app isn't installedZ. My guess is that the former is yes, and the latter is no. - Andrew

[TOPIC: post.html]
#11

beckslash

[GLOBAL: userInfoPane.html]
beckslash
  • Contributor

  • 113 posts
  • Corona SDK

@Naomi Indeed, you need to have native Fb. I don't remember if I tested without the native Fb after I implemented that fix. Will do that tomorrow and see if it's an issue.

 

But I think everyone uses FB with native apps nowdays.

 

Will post my results tomorrow...



[TOPIC: post.html]
#12

Naomi

[GLOBAL: userInfoPane.html]
Naomi
  • Corona Geek

  • 2,303 posts
  • Enterprise

Thank you, Andrew @aukStudios and @beckslah.  
 
I don't have Android device with 2.2 (or below), so maybe that's why I am unable to reproduce the issue myself? 
 
Here's what I also tried.  I installed two separate game app on Samsung Galaxy 3 (with Android 4.1.2), and they both worked fine (i.e., I installed both Corona App A and Corona App B, and then signed in to FB via Corona App A, and then signed in to FB via Corona App B, and they both went through the 3 step login process I described.)
 
Incidentally, I also tried calling facebook.logout before calling facebook.login (but not during event.type == "sessions"), and it gave me java.lang.NullPointerException, so that won't do.  I guess I would need to include the proper workaround that @beckslah posted in the linked thread.  
 
Hmmm… but how big is Android 2.2 user base?  I don't like adding lines of code that I can't quite verify properly.
 
Naomi


[TOPIC: post.html]
#13

beckslash

[GLOBAL: userInfoPane.html]
beckslash
  • Contributor

  • 113 posts
  • Corona SDK

I tested on Android v 4.1.2

 

So my solution only works flawless if the user has the native Fb app installed. If he's prompted to enter his username and password within our app, calling the facebook.logout() method and asking for the writing permission results in having the user enter the username and password again.

 

There's no way to see which login flow to use. But since my guess is that every avid Facebook user will have a native app installed, I'm going to use the one that fixes the native facebook app problem. And since this way doesn't break the other one (which is used by less users), but only adds an extra step in the process, I think that's the way to go for now...



[TOPIC: post.html]
#14

Naomi

[GLOBAL: userInfoPane.html]
Naomi
  • Corona Geek

  • 2,303 posts
  • Enterprise

Thank you, @beckslash.  Yes, I installed Facebook app on Samsung Galaxy S3 (Android 4.1.2), and I see exactly what you are seeing now.  Yikes.  This is pretty bad.  

 

Andrew @aukStudios and @beckslah, have you filed this bug with Corona?  This needs to be fixed for Corona apps that integrates FB.  

 

@beckslah, it's great that you found the workaround to bridge the issue for the immediate needs, but I think this bug should be dealt with and fixed rather quickly.  It basically makes FB implementation for Android device useless.

 

Naomi



[TOPIC: post.html]
#15

Naomi

[GLOBAL: userInfoPane.html]
Naomi
  • Corona Geek

  • 2,303 posts
  • Enterprise

I went ahead and filed the bug.  I'll post the case number as soon as I get it.

 

Edit:  And the case number is 25128.

 

Naomi



[TOPIC: post.html]
#16

aukStudios

[GLOBAL: userInfoPane.html]
aukStudios
  • Corona Geek

  • 1,003 posts
  • Corona SDK

I'm not convinced it's a bug though. I think this is the intended Facebook behavior when interfacing with their app. It should be possible to tell whether the Facebook app is installed or not, and handle it differently then. I remember serig some posts about how to tell on Android whether another app is installed. - Andrew

[TOPIC: post.html]
#17

Naomi

[GLOBAL: userInfoPane.html]
Naomi
  • Corona Geek

  • 2,303 posts
  • Enterprise

Hey, Andrew @aukStudios, I still think it's a bug, assuming this is an issue only with Android version (and not with iOS  that has native Facebook app installed and signed in.)  To be honest, I have not had a chance to test this on iOS.  So far, what I know is that this problem occurs only if Facebook app is installed and the user is signed in to Facebook via the Facebook app prior to signing in to FB via Corona app the first time around.

 

I don't think Corona app should be seeing the ugly alert "SoAndSo app would like to access your email address and post to your friends on your behalf."  And then tapping on "OK" shouldn't automatically bring up "Login Failed" alert.  Meanwhile, on terminal, all I see is isError = false and didComplete = nil and Session Status = loginCancelled.  I don't think this callback response can be meaningfully handled.

 

That said, I like the prevention mechanics you mentioned (i.e., detecting if the user has already installed Facebook app, and choosing the login process accordingly.)  But if that's the only way to handle it, and if the issue really is a conflict with native FB app (and no other app) and Corona app with FB, shouldn't Corona handle this conflict?

 

Naomi



[TOPIC: post.html]
#18

beckslash

[GLOBAL: userInfoPane.html]
beckslash
  • Contributor

  • 113 posts
  • Corona SDK

The pop-up thing is actually because they want to make the process work faster I guess. I find it easier to just tap "Ok" then go through all the Facebook screens. It wouldn't be a problem if corona would handle both cases accordingly.

 

I'm not sure how it's done if you're coding an Android app in native, but there must be a flow-chart on how to implement the new changes Facebook introduced without causing any problems. Corona should investigate and update that in the spirit of code once, work everywhere.



[TOPIC: post.html]
#19

Naomi

[GLOBAL: userInfoPane.html]
Naomi
  • Corona Geek

  • 2,303 posts
  • Enterprise

And here's how it goes with Nexus 4 with Android v4.2.2:

 

1)  Installed Facebook app, launched and signed in.

 

2)  Installed Corona app with FB, and the sign in process is broken.

 

3)  Back to Facebook app and log out.  Delete Corona app, reinstall, and try signing in -- still broken.

 

4)  Uninstall Facebook app, try Corona app and sign in to FB -- finally works.

 

5)  Incidentally, after Corona app successfully signs in to FB, reinstalling Facebook app does not cause any issue with already installed Corona app with user already signed in to FB.

 

With Samsung Galaxy S3 with Android v4.1.2, all I had to do was deactivate Facebook app to get the sign in to work (i.e., I didn't need to uninstall Facebook app.)

 

I went through more than a month worth of Facebook issue with Corona earlier in the year (spending hours after hours, reporting the problem I was dealing with, checking, re-checking, tripple-checking, etc.) -- but ultimately, Corona, thankfully, fixed the issue so that we don't have to add all sorts of messy workaround code.  This time, I really don't want to go down the same path, making changes to the already nicely put together code just to accommodate for the broken FB sign in process stemming from Facebook app.  I mean, it's about Facebook created Facebook app that is conflicting with Corona app with Facebook feature.  I honestly think Corona would want to address this and provide a solid/official workaround. 

 

Naomi



[TOPIC: post.html]
#20

Naomi

[GLOBAL: userInfoPane.html]
Naomi
  • Corona Geek

  • 2,303 posts
  • Enterprise

Apparently, the very same behavior is observed by apps that are built with Corona daily build 1075 (and is already out in Google Play for several months.)  See Philippe's reply post here:

 

http://forums.coronalabs.com/topic/37566-facebook-on-htc-desire-c-vs-sony-xperia/

 

Naomi



[TOPIC: post.html]
#21

Naomi

[GLOBAL: userInfoPane.html]
Naomi
  • Corona Geek

  • 2,303 posts
  • Enterprise

I am sooo happy to report that the case #25128 I filed has been addressed and the issue I described above is now fixed as of daily build 1179.  Yippee!  Thank you, Corona Labs Team!

 

Naomi



[TOPIC: post.html]
#22

bpollet

[GLOBAL: userInfoPane.html]
bpollet
  • Enthusiast

  • 30 posts
  • Corona SDK

There may already be enough info here for everyone but I wanted to add in my experience with this problem to try and help the next person that runs into it.

 

I was getting two different kinds of errors that both stemmed from not having the key hash correct between my app and Facebook. If the Facebook app is installed on the device you have to have the key hash correct or your sign-on will fail. On older Android devices I was getting the 'incorrect key hash' error and on newer devices the Facebook app would return a 'loginCancelled' event to my app even when I accepted the facebook connection by hitting the 'ok' button. After looking at the logs I found that Facebook was throwing an error saying 'remote_app_id does not match stored app_id'. All of these problems were resolved once I got my key hash configured correctly.

 

Correctly creating a keystore/key hash is a two step process. I had created a keystore several months ago on a different laptop and was trying to create the key hash for Facebook off that key. No matter what I tried it wasn't working, until I went back and created a new keystore. 

 

So, if you're still having issues like these try these steps. ( I'm posting steps for Mac OS X )

 

1. In the terminal, move to the directory where you want to store your keystore file. Then create a new keystore for your application like this: ( where APP_NAME is your app's name with no spaces)

sudo keytool -genkey -v -keystore APP_NAME.keystore -alias APP_NAME_key -keyalg RSA -validity 999999

 

You will first be asked to enter YOUR USER PASSWORD. Then during the key generation process you'll be asked for a new keystore password, remember it! You're going to need it in the following steps.

 

2. Once the keystore is generated you can now export the keyhash that you'll need to give to Facebook.

 

keytool -exportcert -alias APP_NAME_key -keystore APP_NAME.keystore | openssl sha1 -binary | openssl base64

 

 

You'll need to enter the same password that you entered for your keystore. This command will spit out a long string, this is your key hash.

 

3. Now you can log in to the Facebook developer console at http://developers.facebook.com and paste the key hash into the 'Key Hashes' box in the Native Android App section of the app settings.

 

4. When you build your app for Android you'll need to browse and select the newly created keystore file and select your key alias from the drop down menu. You will be asked to enter your keystore password again at this point.

 

Following these steps fixed the problems for me. My conclusion is that either the keystore is tied to the machine it was created on and therefore my hash was being exported incorrectly, or I had confused the password I used to generate my keystore and wasn't entering the correct password when I tried to export the key hash.

 

I got this to work with Daily Build 2013.1234, I hope this helps someone else.




[topic_controls]
[/topic_controls]