Facebook frustrations

I know there were changes between 1202 and 1260 (and the G2.0 builds and later)

You may need to upgrade  to 2100 to address this.

Rob

hi rob,

okay i’ll give that a go.

With all the flood of information and forum posts it’s hard to keep track of what’s current and what’s not.

Do we still need a basic facebook login before logging in with permissions?

or can I just do thisas my first call to facebook:

   facebook.login( fbAppId, facebookListener, {“publish_stream”} )
 

function facebookListener( event )

   if ( “session” == event.type ) then

        if ( “login” ~= event.phase ) then
            facebookAlert(“Facebook failed!”, “Please try again”)
            return
        end

        facebook.request(“me/feed”, “POST”  , {message = message} )

thanks

If things work like we want them to, you should only have to call facebook.login() once with the caveat that if the token expires you may have to call it again to re-login.  So generally you should probably call it when you resume from a suspend event.

Rob

Hello Rob,

I wish it was that simple

In case of Android with Facebook app installed:

When you are in your game and user will remove the app from Facebook, the next time you do a facebook.login, you will receive the response as usual, without any errors. When you will try to perform facebook.request, you will receive an error:

type - request

name - fbconnect

isError - true

Immediately after that, you will also receive this:

type - session

name - fbconnect 

phase - logout

isError - false

If you issue a new facebook.login, user will be asked for permissions etc. everything will work fine, not however, that in order to get to this point, you have to perform facebook.login TWICE. First time will end up with a logout, second time will end up with a logged in user or a cancellation.

In case of iOS with FB app installed it works a little bit different

The first part is the same: you issue facebook.login, you receive everything as usual, you issue facebook.request and you receive the error as described above. Unfortunately this is where everything ends. There’s no automatic logout.

What’s better, you cannot just do it on your own and issue facebook.logout hoping for the best. You cannot issue facebook.login as well, simply because both of them will yiled no results.

You have to create a timer, [in my case 1 second was enough] and issue facebook.logout manually. Now this call does not return anything, but from my experience and testing I performed yesterday, it is necessary.

After this, I create another timer, 3 second was enough in my case, and I do a facebook.login. This time it will work and user will be asked for permissions.

Unfortunately, this ends with application crashing, however the next time user opens up the app - they are logged in [or not if they chose not to log in].

Because this is a very rare case that someone will remove the app from facebook while playing the game, I decided that the app crash is not a showstopper [also, because there’s nothing more I can do using Corona, and I am not ready to switch to my own fb handling - I’ll do so with my next app].

Anyway… here are my experiences with the app I’m developing. 

I’ll let you know if there’s something else going on without the fb app installed.

Hi Rob,

I’ve upgraded to 2100 and still the same events:

I/Corona  (11601): event.name   fbconnect
I/Corona  (11601): event.type:  session
I/Corona  (11601): isError: false
I/Corona  (11601): didComplete: nil
I/Corona  (11601): response :
I/Corona  (11601): phase : loginCancelled

I can confirm the upgrade because all the graphics were out of whack.

I’ll post my code now in the hope that you or someone else might spot something.  Thanks for your time if you’re able to.

regards

Daniel

facebook.lua (the function facebookPostStartGame() gets called from another file)


facebook = require( “facebook” )

fbAppId = “188128428059002”
facebook.publishInstall(fbAppID)

local LOGOUT = 1
local SHOW_DIALOG = 2
local POST_MSG = 3
local POST_PHOTO = 4
local GET_USER_INFO = 5
local GET_PLATFORM_INFO = 6

local facebookMessage = “”

function facebookListener( event )

    print( “event.name”, event.name )  --“fbconnect”
    print( “event.type:”, event.type ) --type is either “session”, “request”, or “dialog”
    print( "isError: " … tostring( event.isError ) )
    print( "didComplete: " … tostring( event.didComplete ) )
    print("response : " … tostring(event.response))
    print("phase : " … tostring(event.phase))        – tjn Added

    --“session” events cover various login/logout events
    --“request” events handle calls to various Graph API calls
    --“dialog” events are standard popup boxes that can be displayed

   if ( “session” == event.type ) then

        if ( “login” ~= event.phase ) then
            facebookAlert(“Facebook failed!”, “Please try again”)
            return
        end

        print(access_token)
        access_token = event.token

        if fbCommand == GET_USER_INFO then
            facebook.request(“me”)
        elseif fbCommand == POST_MSG then
            facebook.request(“me/feed”, “POST”  , {message = message} )
        end
    elseif ( “request” == event.type or “dialogue” == event.type ) then
        local response = event.response

        print("Response: ",response)

        if ( not event.isError ) then
            if fbCommand == GET_USER_INFO then
                response = json.decode( event.response )
            elseif fbCommand == POST_MSG then
                facebookAlert(“Facebook Successful”, “You’ve successfully shared your score!”)
            end
        else
            facebookAlert(“Facebook failed!”, “Please try again”)
        end
    end
end

function facebookAlert(popupTitle,popupMessage)
    native.showAlert( popupTitle, popupMessage, {“OK”} )
end

function postToWall(msg)
    message = msg
    fbCommand = POST_MSG
    
    print(“initial login”)
–    facebook.login( fbAppId, facebookListener)
–    print(“logout”)
–    facebook.logout()
–    print(“login with permissions”)
   facebook.login( fbAppId, facebookListener, {“publish_stream”} )
end

function shareGame()
    message = “The Best Cricket Game Ever http://www.bestcricketgame.com
    fbCommand = POST_MSG
    facebook.login( fbAppId, facebookListener, {“publish_stream”} )
end

function facebookPostStartGame()

    message = “TESTING 123 PLEASE IGNORE I’ve just started The Best Cricket Game Ever.  My team … " … playerTeam … " is up against " … computerTeam … “.  " … tossWonBy
    … " won the toss and elected to " … tostring(getTossChoice()) … " on a "
    if pitchType == 1 then
        message = message … " great batting wicket.”
    elseif pitchType == 2 then
        message = message … " pitch that will assist both batters and bowlers.”
    elseif pitchType == 3 then
        message = message … " great bowling wicket."
    end
    
    message = message … "  The players are now off to the middle to start the action.  If you’d like to play, visit http://www.bestcricketgame.com or search for ‘The Best Cricket Game Ever’ in the App Store or Google Play."
    
    postToWall(message)
end
 


And my build.settings


settings =
{

    iphone = {
        plist = {

            UIApplicationExitsOnSuspend = false,

            FacebookAppID = “188128428059002”,  --replace XXXXXXXXXX with your Facebook App ID

            CFBundleURLTypes = {
                {
                CFBundleURLSchemes = { “fb188128428059002”, }  --replace XXXXXXXXXX with your Facebook App ID
                }
            },
            
            [“URL types”] = {
                item = {
                    [“URL Schemes”] =
                        { [“Item 0”] = “fb188128428059002” },  --replace XXXXXXXXXX with your Facebook App ID
                },
            },            
        }
    },
    
    android =
    {
    versionCode = “1”,
    installLocation=“preferExternal”
    },

    androidPermissions =
    {
       “android.permission.READ_PHONE_STATE”,
       “android.permission.ACCESS_NETWORK_STATE”,
       “android.permission.VIBRATE”,
       “android.permission.INTERNET”,
        “android.permission.ACCESS_WIFI_STATE”,    
        “android.permission.ACCESS_FINE_LOCATION”,
        “android.permission.ACCESS_COARSE_LOCATION”,        
        },

    plugins =
    {
      --key is the name passed to Lua’s ‘require()’
     [“CoronaProvider.native.popup.social”] =
      {
        --required
        publisherId = “com.coronalabs”, – don’t change, is’t the publisher of the plugin
      },
      
      
        – key is the name passed to Lua’s ‘require()’
        [“CoronaProvider.ads.admob”] =
        {
            – required
            publisherId = “com.coronalabs”, – don’t change, it’s the publisher of the plugin
        },
        
        – key is the name passed to Lua’s ‘require()’
        [“CoronaProvider.ads.vungle”] =
        {
            – required
            publisherId = “com.vungle”,
        },
        
    },

  orientation =
    {
        default = “portrait”,
        supported =
        {
        “portrait”,
        },
                    
    },
    

}


thx

Daniel

This thread is kinda long, so help me out, @editor are you sure your hashkey is right? 

Rob

Hi Rob,

From what I’ve read a few people have had problems with characters being replaced by other characters when they shouldn’t.  But I think they also had error messages that specifically mentioned the hashkey problem.    I don’t have any error message to go on at all, just a loginCancelled event.

Copy/Paste from Facebook my hash is:

qMSzTuC5qly67dJxDMzrToeQRHw=

I’ve tried to find out what I’m comparing it to, but the Corona documenation is now outdated as facebook has updated their site

the link

https://developers.facebook.com/docs/getting-started/facebook-sdk-for-android/3.0/

no longer works.

How can I work out what I’m meant to be comparing it to?

thanks

I found this:

http://stackoverflow.com/questions/4388992/key-hash-for-android-facebook-app

Seems there’s more than one way to get a key hash, and they don’t all work properly!

I’ll have a play and see what I find.

Usually in this case, I like to see the build screen that you’re building against.  Then I’d like to see the command you are entering to create your hash key.

Rob

Hi Rob,

I don’t have the command that produced the original hash anymore.  Pretty sure I used the one that was in the Facebook tutorial that was linked from the Corona facebook documentation (which has now moved somewhere else).  A post I found on StackOverflow seemed to indicate that generally the given windows commands don’t work.  They said to use different parameters, so this is what I’ve used:

keytool -export -alias cricket -keystore C:\Users\daniel kirk\Dropbox\Best Cricket Graphics 2.0\bestcricket.keystore | openssl sha1 -binary | openssl en -a -e

From the build screen, I copy/paste the keystore:

C:\Users\daniel kirk\Dropbox\Best Cricket Graphics 2.0\bestcricket.keystore

I’m pretty sure the alias and package name are all matched up correctly.

In facebook, I’ve got both the hash from the command above, and the original hash has been kept too.

Using this new hash, I’ve got the same problem as the old one

Here’s the event data again:

I/Corona  (15165): event.name   fbconnect
I/Corona  (15165): event.type:  session
I/Corona  (15165): isError: false
I/Corona  (15165): didComplete: nil
I/Corona  (15165): response :
I/Corona  (15165): phase : loginCancelled

thanks again!

Daniel

Hi Rob,

One thing I wasn’t sure about was which version of openssl to download for Windows.  How do I know if I should use 32 or 64 bit?

I’ve been using 32 bit, I just tried 64 but the keytool command didn’t work as apparently ‘en’ is not a valid option with it.

I don’t know much about the difference between the 32 and 64 bit versions but I would think the 32 bit version would be the safest.

The command that you get from facebook’s documentation is based on using a debug keystore (and not a release one) and it assumes that you use the keystore in the Android SDK folder.  Corona SDK uses a default debug keystore that we distribute with Corona and they are different debug keystores.  This is why I want to see your build screen to see what keystore you are really using.

The default windows example assumes the keystore is in a specific place and for some people that’s not where their keystore is.  We’ve tried to explain everything here:

http://coronalabs.com/blog/2013/07/30/understanding-facebook-authentication/

The way the command’s are pipelined through each other, you are going to get a keyhash when you are done, regardless of if the keytool command actually output anything or you putting in a correct password.  Usually Facebook tells you in the adb logcat output that the keystore is wrong and what it’s expecting, though you can’t exactly copy/paste that string because of the missing = sight at the end and I think another character may not be right. 

The log message will likely not be generated by Corona so if you’re doing the adb logcat with Corona on the command line, it’s likely filtering out the message from Facebook.

Just do:

adb logcat

and look for keystore error messages.

Rob

Hi Rob,

I found this message in adb:

W/fb4a(:<default>):BlueServiceQueue(15071): com.facebook.http.protocol.ApiExcept
ion: Key hash EtKha0DGwILWPU6JviNQMTfSfvg does not match any stored key hashes.

The reason I didn’t post a screenshot of my build screen is that last time I tried that in this forum it said that it “couldn’t accept files of this type.”

But I did copy/paste from the build screen…

Keystore : C:\Users\daniel kirk\Dropbox\Best Cricket Graphics 2.0\bestcricket.keystore

Which to me looks like it matches what I’ve got in the command:

keytool -export -alias cricket -keystore C:\Users\daniel kirk\Dropbox\Best Cricket Graphics 2.0\bestcricket.keystore | openssl sha1 -binary | openssl en -a -e

I’m going to start from scratch and see what happens.  Wouldn’t have a clue where I could have gone wrong though

The log file tells you what the Key should be:
 

EtKha0DGwILWPU6JviNQMTfSfvg

but it’s missing the = at the end, so try:

EtKha0DGwILWPU6JviNQMTfSfvg=

Rob

Hey Rob,

Merry Christmas!   I spent a day fiddling with changing this variable and that variable to get the Corona Scrumptious sample app to work.   In the end, when I entered the Facebook App ID into the loginScreen.lua file, I entered it without quotes, hence it was not a string.  Oy!  Also, you need to enter the Facebook App ID into the mainScreen.lua file (also as a string).

Never got an error message that indicated that was a problem.  Cost me about 8 hours of troubleshooting!   Just a warning for others. 

any solutions on this… im also getting the loginCancelled… hash all setup properly…

Hello,

I wrote up a tutorial for Facebook for Android debug builds right here:

http://forums.coronalabs.com/topic/42655-facebook-101-for-android-debug-build/

Hopefully that helps!

any solutions on this… im also getting the loginCancelled… hash all setup properly…

Hello,

I wrote up a tutorial for Facebook for Android debug builds right here:

http://forums.coronalabs.com/topic/42655-facebook-101-for-android-debug-build/

Hopefully that helps!

Hi,

I’m having headaches already…

Platforms: I’m having problems with both.

Corona SDK: 2014.2189 (2014.3.6)

Facebook operation: I’m trying “apprequest”, but it’s not working. I only got “the page you requested was not found” message.

Friend list when i use the “showDialog(“friends”, onComplete)” it’s empy.

Login, logout and self publishing works fine. 

----------------------------------------------------------------------------------------- -- -- main.lua -- ----------------------------------------------------------------------------------------- local facebook = require("facebook") local widget = require("widget") --ID de la aplicación local FBAppID = "521039174688673" local function onComplete( event ) print("event.name:", event.name) print("event.type:", event.type) if (event.data) then print(" { ") for k, v in pairs( event.data) do print(k, " : " , v) end print(" } ") end end local function listener( event ) print( "event.name", event.name ) --"fbconnect" print( "event.type:", event.type ) --type is either "session", "request", or "dialog" print( "isError: " .. tostring( event.isError ) ) print( "didComplete: " .. tostring( event.didComplete ) ) if ("session" == event.type) then if ("login" == event.phase) then facebook.showDialog("apprequest", {message="Prueba de invitación"}) end elseif ("dialog"==event.type) then print(event.response) elseif ("request" == event.type) then print(event.response) end end -- muestra amigos local function showFriends(event) if (event.phase =="ended") then facebook.showDialog("friends", onComplete) end return true end -- Ventana emergente para publicar en el muro local function publishFeed( event ) if (event.phase == "ended") then --facebook.request("me/feed", "POST", {message="Probando librerias de FB para Corona. Disculpen las molestias"}) facebook.showDialog("feed", {message="más pruebas de desarrollo"}) end return true end -- peticion de instalacion local function appRequest( event ) if (event.phase == "ended") then facebook.showDialog("apprequest", {message="Probando a invitar amigos..."}) end return true end -- login en facebook local function login( event ) print("---------------- entrando en método de login") if (event.phase == "ended") then --login facebook.login(FBAppID, listener, {"publish\_actions"}) print( "------------------- login realizado" ) --Registro de instalación en la web print ("------------------- registrando instalacion") facebook.publishInstall(FBAppID) print( "------------------- registro realizado" ) --buttonFriends:setEnabled( true ) --buttonPublish:setEnabled( true ) --buttonAppRequest:setEnabled( true ) --buttonLogin:setEnabled( false ) end return true end -- logout local function logout( event ) print("---------------- entrando el el método de logout") if (event.phase == "ended") then facebook.logout( ) print( "--------------- logout realizado" ) end return true end -- elementos de la interfaz local buttonLogin = widget.newButton{ label = "Login", onEvent = login, x = display.contentCenterX, y = display.contentCenterY - 120 } local buttonLogout = widget.newButton{ label = "Logout", onEvent = logout, x = display.contentCenterX, y = display.contentCenterY + 120 } local buttonFriends = widget.newButton{ label = "Elige amigos", onEvent = showFriends, x = display.contentCenterX, y = display.contentCenterY - 40 } local buttonPublish = widget.newButton{ label = "Publicar en mi muro", onEvent = publishFeed, x = display.contentCenterX, y = display.contentCenterY + 40 } local buttonAppRequest = widget.newButton{ label = "Peticion", onEvent = appRequest, x = display.contentCenterX, y = display.contentCenterY + 80 }

And build.settings

-- Supported values for orientation: -- portrait, portraitUpsideDown, landscapeLeft, landscapeRight settings = { orientation = { default = "portrait", supported = { "portrait", } }, iphone = { plist = { UIStatusBarHidden = false, UIPrerenderedIcon = true, -- set to false for "shine" overlay --UIApplicationExitsOnSuspend = true, -- uncomment to quit app on suspend FacebookAppID = "521039174688673", -- iOS app URL schemes: CFBundleURLTypes = { { CFBundleURLSchemes = { "fb521039174688673", -- example scheme for facebook } } } } }, --Prueba de facebook plugins = { ["facebook"] = { publisherId = "com.coronalabs", supportedPlatforms = {iphone=true, ["iphone-sim"]=true}, }, }, -- Android permissions androidPermissions = { "android.permission.INTERNET", }, }

Thanks.