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
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
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.