Please can someone clarify why we have to login twice for email and friends permission

Hi Rob,

Just wondered if you had chance to read my last post?

I also got a response back about the bug I logged (34216) from Tom saying that “There have been a number of Facebook fixes in the latest Facebook SDK that was added to a Daily Build”  - however I thought that because facebook for ios is a plugin it is not affected by daily builds?

I also asked Tom what changes (in particular my issue) had been made but as yet I’ve had no response.  Do you know if this issue was part of the fixes? 

Cheers

On iOS it’s a plugin and should not be dependent on daily vs. public builds.  However on Android, its still in the core and the daily build matters.

I spent a lot of time reading the Facebook API docs around login and permissions, and while the first long probably should allow you to ask for email and user_friends, it’s not wrong  to do it in two passes.   I’ll reply to the bug, and add some context to it, but it seems to me that you can do the two logins and still work.  Facebook is very clear that you should ask for public_profile first and then ask for other things when you need them. 

Rob

Hi rob, thanks for taking the time to read the facebook docs - its appreciated. I too have spent a lot of time reading it all but feel it was time well spent.  Yes, you are 100% correct that it is not technically wrong to do it in two phases however, why do something in two steps that you can do it one?

I guess the point I was trying to get across is that the user experience is much much better doing it just once. I suppose me calling it a bug is a bit of a misnomer too - more of a “it would be way way better for the end user if it worked in this way”…

If facebook said that it absolutely had to be done in two phases then that is out of your control but as you mentioned… facebook does allow you to ask for multiple read only permissions as first log (even though it recommends doing public profile first - its not mandatory) so really corona should allow you (the developer) to do that also if you choose to.

Anyway, thank you very much for listening to me bang on about this haha! and thanks for updating the bug on my behalf.  

As you said, it does still work but it is clunky so I’ll cross my fingers I hope it gets resolved…

Would it help if I promised to upgrade to PRO once the bug is fixed plugin is enhanced?? ;)   I actually would  :stuck_out_tongue:

Cheers

Dave 

I just wanted to say that I’m with Dave on this, not that the plugin is broken, but having a two-phase login seems like bad user experience to me and it would be nice if it could work the way Facebook states how all read only permissions can be asked for in the first step.

I’m having issues with my users because they accept the public profile, but then when they are brought to Facebook a second time it asks for the friend list, it seems they are declining it. My app REQUIRES friend list so it confuses the user why they can’t log in, even though they did allow access to Facebook. I can pop up alerts explaining to the user why they cant log in but again, bad user experience.

It would just be nice if the outcomes could just be:

A ) not login and give facebook no permissions 

or

B ) login and give facebook both permissions

But the way it is implemented now opens up a whole new outcome:

C ) login and have a missing permission

I don’t want the user to be even logged in at all if they have the missing friend_list permission.

As a side note because the publish_actions is not the topic in the forum, I do ask for the publish_actions permission later on in the app when the user is asked if they would like to share a post, and that works nicely because its an optional permission in my game.

Love to know if this is something still being looked into.

Thanks,

Evan

Ps I do have a PRO account :wink:

Hi Evan,

Thanks for chipping in - i was beginning to think it was just me that was thinking this…  can I ask - have you read all the facebook docs too?  is that how you came to the same conclusion I did?  

As you said, its not that the plugin in broken per se - its just the (unnecessary) bad user experience it seems to give.

I would imagine this is low on corona’s list since it does “work” but it would be great if they could just tweak the plugin for us :slight_smile:

I did raise a bug but no idea what the progress is or whether it has been considered a non issue, etc…  Don’t suppose you know where the page is for checking where a bug case is at?

Cheers

Yes, I read all the Facebook documention and that is what led me to this forum.  I figured there must be someone else finding this a problem, but it seems it might only be us.

The problem is it doesn’t seem to be reliable calling this line at all:

facebook.login( appId, callFacebook, {"public\_profile", "user\_friends"} )

But instead what seems to fix my users issues when logging in is using the plugin like this

facebook.login(self.fbAppID, facebookListener, {'public\_profile'} )

Then once Facebook returns the login worked, call

facebook.login(self.fbAppID, facebookListener, {'user\_friends'} )

It seems that sometimes, not sure what my user’s are doing, it wont even ask again for user_friends the first way and that is what is preventing them from logging in. The weird thing is, give it a day or 2, the users can successfully log in to Facebook with no change to their privacy settings on Facebook.

According to this document, http://docs.coronalabs.com/daily/guide/social/implementFacebook/index.html, the first way should work.

Sorry Dave, I’m not sure how to check the progress on a bug case.

Can someone try this now?  Engineering said they fixed this in the plugin today. 

Rob

Rob - what a legend!   :)  :smiley:

I just deleted my app from facebook, rebuilt my app, logged in with facebook and the very first time I get public profile, friend list AND email!!  The process feel so streamlined now!

Really appreciate you getting someone to look at this, Rob.  I know this was probably a low priority given all the other things you are no doubt working on but this is a massive improvement for the facebook plugin.

Maybe if Evan could check things in his app too (just in case I’ve done something wrong) just to confirm but this is great news for me!

Anyway, next paycheck - looks like I’ll be upgrading my account haha  :wink:

Is it cheeky to now ask if the same will happen for android ;)  ?  (appreciate that is part of the core so might not be quite as quick / easy)

Thanks again

This fix did not make it into the recent public build.  Facebook is not a plugin on Android, so this will have to wait until daily builds resumes before we can apply this for Android… if it’s a problem there.  It may be working already.

Rob

Works great now!  :D  Thank you so much Rob, Dave, and the Engineering team!

Might have spoke too soon. Is this the expected behavour?

The ‘Connect’ button is always calling:

facebook.login(self.fbAppID, facebookListener, {'public\_profile', 'user\_friends', 'email'} )

But every other time this code is executed it alternates from asking for only public profile (not what I want), to asking for all 3 (which is what I want), starting with only public profile.

Here’s a video to show the behaviour:

http://www.dropshots.com/ebarnes/date/2014-08-11/11:18:24

Can you post your login code?

Evan…

I watched the video - can you confirm that you are doing this (so I can replicate exactly the same process for comparison):

  1. Ensure app has been removed from FB

  2. Open app

  3. click on connect - goes to FB with one permission requested

  4. click cancel on facebook dialog - goes back to your app

  5. click on connect - goes to FB with three permissions requested

  6. etc, etc

If so, I will try the same but for me if I follow steps 1 - 3 the first display of the FB screen always shows 3 permissions now

I’m not at home now but I’ll post my login code too if that helps later on

Cheers

Dave

Okay I have more information. Hopefully this helps!

  1. Ensure app has been removed from FB

  2. Open app

  3. click on connect - App logs in even though it was removed from facebook:

    type=session name=fbconnect expiration=1413034972 phase=login token=CAAKMoE4EGGEBAFMZAUjVLhXEhmKqA1ZBZAN1nTUZCBDQTrfpEWWq9ju8XKCGOejaVqVPRO738UuDRgoBgbZAlwZAbwOVOwwPuzd2ZBoGfmQlbDzqqXTYQwvRVZAZCezIGZB3SQfEP71INogpJ3gX16sCSFZBcF4YotRZCNwB8myXuMwREQZBMUcp9cWfGcYdS9x3lxyaoyCjb2PgDO1kqZ isError=false response=nil

  4. App understands that a login was successful and automatically calls facebook.request(‘me/permissions’)

  5. Facebook listener returns:

    type=session name=fbconnect phase=logout isError=false response=nil isError=true type=request name=fbconnect response=The operation couldn’t be completed. (com.facebook.sdk error 5.)

  6. Since the app wasn’t apple to get permissions, it shows the connect button again.

  7. Click on connect and because its the second login technically, it only shows the public_profile permissions

It seems that for some reason it still logins in (which it shouldn’t correct?), but once a new request is called it automatically logs the user out and returns the “com.facebook.sdk error 5”.

What am I doing wrong to get this. If this never occurs, I would be getting the results like Dave where it shows all 3 permissions first.

Here’s my code:

local function facebookListener( event )     if (User.state == 'login') then                  if event.type == "session" then                      if event.phase == "login" then                 User.fb\_sessionToken = event.token                    User.fb\_sessionExpiry = event.expiration                              User.onComplete()             elseif event.phase == "loginFailed" then                 User.onError()              end         end     elseif (User.state == 'permissions') then                  if event.type == "request" then                      local response = json.decode( event.response )                          if event.isError == false and response~= nil then                                      local missingPermission = true                                  if (response.data ~= nil) then                     for i=1, #response.data do                         local data = response.data[i]                         if (data.permission == 'user\_friends' and data.status == 'granted') then                             missingPermission = false                             break                         end                     end                 end                                   if (missingPermission == true) then                      User.onError()                  else                      User.onComplete()                  end             else                 User.onError()             end         end     elseif (User.state == 'me') then                  if event.type == "request" then                      local response = json.decode( event.response )                          if event.isError == false and response~= nil then                 if (response.id ~= nil) then                     User.fb\_userID = response.id                                    User.name = response.first\_name                               end                                   if (response.email ~= nil) then                         User.email = response.email                 end                                   User.onComplete()             else                    User.onError()             end         end     elseif (User.state == 'friends') then                  if event.type == "request" then                                   local response = json.decode( event.response )                          if event.isError == false and response ~= nil and response.data ~= nil then                                 User.fb\_friends = response.data                   User.onComplete()             else                    User.onError()             end         end     end end function User:LoginToFacebook(onComplete, onError)          local function checkPermissions()              local function getMyInfo()                          local function getFriendsInfo()                              self.state = 'friends'                                  local function loginToParse()                                          local function loginSuccessful()                         self.isLoggedIn = true                                                  onComplete()                     end                                          self.onComplete = loginSuccessful                                          self.onError = function()                         onError()                     end                                          self:doParseLogin()                 end                                      self.onComplete = loginToParse                                  self.onError = function()                     onError()                 end                                  facebook.request( "me/friends" )             end                          self.state = 'me'                          self.onComplete = getFriendsInfo                          self.onError = function()                 onError()             end                      facebook.request( 'me' )         end                  self.state = 'permissions'              self.onComplete = getMyInfo                  self.onError = function()             onError()         end                  facebook.request( 'me/permissions' )     end          self.state = 'login'          self.onComplete = checkPermissions          self.onError = function()         onError()     end          facebook.login(self.fbAppID, facebookListener, {'public\_profile', 'user\_friends', 'email'} ) end

Also note, after the weird logout occurs, the steps in Dave’s post will always show all 3 permissions the first time like he is experiencing.

What is the code for your onError() function?

It’s just GUI calls like:

button.isEnabled = true activityIndicator:stop()

I don’t see where you’re calling login a second time.

seems to be a problem there too… for me at least

I don’t call login a second time. There is a ‘Connect’ button on my app that calls login. I press it the first time (step 3 in my earlier post), and then because it fails and gets a sdk 5 error, press it a second time (step 7) and it brings me to Facebook permission page but only showing public_profile permission.

The problem is when I delete the permissions through the Facebook app, and launch my game, it logs in successfully. However when I try a request after the login, the request seems to log out the user and return an error for the request.

This wouldn’t be an issue if every other login didn’t alternate between showing 3 permissions to 1 permission. Do you know why it does this?

Lets get a bug filed on it then.  Produce a reproducible test case for engineering please.  Make sure to include your config.lua and build.settings and put it all in a .zip file please.

Rob

Hi Evan / Rob

Sorry for delay in properly responding - I have been away from my pc most of the week so have only just started to do some tests.

I can confirm that I am also getting the weird switching between public profile only and the permissions I want i.e. email and friends.  

I have also managed to replicate this with a very very minimal amount of code which I have posted below…  I have a button that calls fbLogin().  This is the process to replicate

  1. Ensure you have deleted the app from facebook

  2. Open my app and click on my login button

  3. Switches to facebook and shows the correct permission (public, email and friends)

  4. Click ‘Cancel’ and return to my app - event phase is loginFailed which is fine since I cancelled

  5. Click on my login button again 

6) Switches to facebook again but now just shows public permissions

  1. Click ‘Cancel’ - repeat step 2

Evan (and rob if you have time) - can you confirm that you can replicate this behavior consistently using the bare minimum code below? 

local function callFacebook2(event) print( "Facebook Listener events:" ) print( "event.name", event.name ) -- "fbconnect" print( "event.type:", event.type ) -- type is either "session" or "request" or "dialog" print( "isError: " .. tostring( event.isError ) ) print( "didComplete: " .. tostring( event.didComplete) ) print( "eventphase:", event.phase) end function fbLogin(event) -- login to facebook and then get user data facebook.login( appId, callFacebook2, {"email, user\_friends"} ) end