Facebook posting on Android

So this is where Im confused. For starters let me say that the documentation that corona offers about this sucks. Im not being PC about it. Its dated, scattered, and really needs to be pulled into one resource.  Now I can find plenty of information about social plugins and libraries for iOS, but the dev team dropped the ball when it comes to documentation for Android.

With that being said, regardless of plugins, is it supported at all? That is my question. I have been at this for weeks, I know how to post to Facebook with native android, throw in corona and the crap hits the fan.  I have sparatic success when it comes to getting things: text, pictures, links, to post to a users wall.  In fact the only way this happens is when the Facebook app is NOT installed on the device, and you have to constantly authenticate through http, but even then things do not post 100%.

Try GGFacebook its a great library for Facebook.

Glitch is a great library.  If I was developing for iOS.  I used them for android and got the exact same result.  Thanks for the reply though, patso

Hi David.  If you can post without the facebook native app installed, then that pretty much points to the fact that your hashkey is not correct.  I don’t know if you’ve read this tutorial or not, but it should help you solve any authentication issues.

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

Rob

No. The key hash is correct.  However it looks like its not logging in correctly to Facebook?

I/Corona  (17968): event.name   fbconnect

I/Corona  (17968): event.type:  request

I/Corona  (17968): isError: true

I/Corona  (17968): didComplete: false

any thoughts? I am just using the example code from the api documentation

FWIW, there have been a good 10 threads created in the past 5 days about issues relating to Facebook integration. Most people’s issues have been resolved by checking the Facebook gotchas, and ensuring they are requiring the Facebook plugin in the build.settings file. I don’t know if that’s your problem, but that has been the issue for most folks.

Well technically no, I did not add the Facebook plugin, because I am trying to post using an android device.  Could that really be the issue?

Nope, I suppose not, since you are using Android that shouldn’t be the issue.

I’ve not used social elements in my apps yet (coming soon) so I’m not going to pretend to be an expert. However, there are some good tips in this forum thread. Specifically, ensuring Facebook is logged in on the device in question.

However, it seems like you’re encountering an issue with logging into Facebook itself. Are you using an existing AppID? What does your facebookListener code look like? Are you passing any permissions during login?

Hey I appreciate all the help I can get.  Yeah I created an app ID in Facebook and copied the number into corona.  as far as the listener I am just using the default in the api documentation

local 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 ) )     --"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         --options are: "login", "loginFailed", "loginCancelled", or "logout"         if ( "login" == event.phase ) then             local access\_token = event.token             --code for tasks following a successful login         end     elseif ( "request" == event.type ) then         print("facebook request")         if ( not event.isError ) then             local response = json.decode( event.response )             --process response data here         end     elseif ( "dialog" == event.type ) then         print( "dialog", event.response )         --handle dialog results here     end end  

I guess why I seem so aggressive in this forum is that I can open intelliJ throw some garbage code in and start posting to Facebook, I try to do tis in corona and not only do I have to (go here, go there, go here, go there) to find the info. I can’t get it to work.  Again I do appreciate the replies  B)

I’m always happy to help!

I could have sworn I was looking at a bunch of forum posts that in order to test with facebook, you need a previously created appID, rather than one that was just made. Usually I’m good with the forum links, but I can’t find this one.

I understand where you’re coming from. The facebook guide points to appIDs, keystores, key hashes, and issues with the build.settings file for a lot of Android users. I’m not really looking forward to implementing this!

Ok I mis-spoke a little.  The app ID is about two weeks old.  If that is not old enough, man I don’t know…

Found it: http://forums.coronalabs.com/topic/44603-facebook-issues/

I’m sure that’s old enough, but I’d suggest debugging with a pre-existing appID, just to confirm that it actually works.

Facebook is not easy because there are too many things that have to be right on their end, and things have to be right on our end and the behavior changes based on the presence of absence of the native app on the device (and now on iOS if they are using the built in Facebook support.)

I would suggest posting a screen shot of your Facebook app setup screen, your build.settings, the screen shot of the Corona SDK Build screen just before you click on the build button, and the facebook related code in your main.lua and let us see if we can spot something.

Though 99 times out of 100, its a keyhash problem with Facebook clearly stating it in the console log when you run adb logcat

without any other parameters.  One of the biggest frustrations is there are different versions of OpenSSL that can be used to generate the keyhash.

Part of the problem with keyhashes too is the fact that you’re asked to execute a pipeline of commands (there are three chained together) and if any of those outputs an error like an Invalid password, it will still give you what looks like a valid keyhash in the end.  The next problem is people just cut and paste the command line commands and execute them without adjusting them for their system.  For instance if you follow Google’s docs, it has you use a debug keystore from some random folder on your computer.  If you build with a debug keystore that Corona Uses, it’s a different debug keystore and your output keyhash won’t work. 

Rob

Actually I built the app using OSX mavs.  Now when I get the key hash I am using from coronas debug keystore that is found in the corona sdk folder. (Im not in front of my mac atm I will be in a day or two).  should I not be using that keystore?  However, no where in my adb logcat am I getting any key hash problems.  Just what I posted above.

I will get some examples posted up soon.  I would like to get this resolved finally, mainly because my subscription is up and I have been on the fence if I want to renew or not.  This would definitely help in that decision.  I have a real love / hate relationship with this platform.

Personally, I would use a release keystore instead of the Debug one. It’s just one less thing you have to change when you launch your app. 

Can you dump your event.response value?  There may be more information there.

Sorry to jump in, but I released my Google Play version of Feather without the ‘share to Facebook’ feature because I read the same as the OP that it’s not working and I didn’t bother to try to implement something that was supposedly broken. Can someone confirm that it actually is? My app simply posts a high score message and screenshot at the user’s request, and it works for Email/text/Twitter using the “social” plugin or native.showPopup function for the iOS and Android devices. I don’t do any complicated setup on http://developers.facebook.com with the App ID/Secret, etc., just post to Wall and go.

logged in remotely to see what my event.response give me.  I get this:

com.facebook.FacebookException: Session provided to a Request  in un-opened state.  

Can you post more code?  Where are you doing the facebook.login() call?  What is your build.settings look like?

Rob

Ok so this will be a bit lengthy, I will keep it as short as possible and post snippets of my code.

build.settings –

settings ={     plugins =     {          -- key is the name passed to Lua's 'require()'         ["CoronaProvider.ads.admob"] =         {             -- required             publisherId = "com.coronalabs",         },         --key is the name passed to Lua's 'require()'         ["CoronaProvider.native.popup.social"] =         {             --required             publisherId = "com.coronalabs",         },              },     orientation =      {         default = "portrait", --landscapeRight         supported =          {             "portrait",         }     },     iphone =     {         plist =         {             UIStatusBarHidden = true,             UIAppFonts =                                      {                 "kenpixel\_mini\_square.ttf"             },             CFBundleIconFiles = {                 "Icon.png",                 "Icon@2x.png",                 "Icon-40.png",                 "Icon-40@2x.png",                 "Icon-60.png",                 "Icon-60@2x.png",                 "Icon-72.png",                 "Icon-72@2x.png",                 "Icon-76.png",                 "Icon-76@2x.png",                 "Icon-Small-50.png",                 "Icon-Small-50@2x.png",                 "Icon-Small.png",                 "Icon-Small@2x.png",                 "Icon-Small-40.png",                 "Icon-Small-40@2x.png"             }         }     },     android =     {         versionCode = "12",         usesPermissions =         {          "android.permission.INTERNET",          "android.permission.ACCESS\_NETWORK\_STATE",          "android.permission.READ\_PHONE\_STATE",         },     }, }  

So in this game there is a main.lua, menu.lua, game.lua files. main.lua is self explanatory which immediately calls menu.lua to start the game. It also stores globals for sound and admob.

menu.lua just holds the intro animation and start button, once tap start we go t game.lua where everything else is handled.

So this brings me to my game.lua file, where I will not post the entire thing (its long…really long) but give you the basic set up of how I am trying to post. I guess I should also mention I am using story boards.

local storyboard = require( "storyboard" )local scene = storyboard.newScene() local physics = require ("physics")    --Require physics local facebook = require( "facebook" ) local json = require( "json" ) local 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(event.response)     --"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         --options are: "login", "loginFailed", "loginCancelled", or "logout"         if ( "login" == event.phase ) then             local access\_token = event.token             --code for tasks following a successful login         end     elseif ( "request" == event.type ) then         print("facebook request")         if ( not event.isError ) then             local response = json.decode( event.response )             print(event.response)             --process response data here         end     elseif ( "dialog" == event.type ) then         print( "dialog", event.response )         --handle dialog results here         print(event.response)     end     print(event.response) end  

…stuff

local fbButton local fbPost fbButton = display.newImageRect(gameGroup, "assets/social\_f.png", 200, 50) fbButton.x = \_W / 2 fbButton.y = \_H / 2 + 100 fbButton.alpha = 0 fbButton:addEventListener("touch", fbPost) -- Transition in the game over screen local transitionDelay = 1000 local transitionTime = 300 transition.to(gameOverImage, {alpha=1, y=\_H/2-170, time=transitionTime, delay=transitionDelay}) transition.to(gameOverScoreboard, {alpha=1, time=transitionTime, delay=transitionDelay}) transition.to(tryAgainButton, {alpha=1, time=transitionTime, delay=transitionDelay}) transition.to(fbButton, {alpha=1, time=transitionTime, delay=transitionDelay}) timer.performWithDelay(transitionDelay + transitionTime, displayScores) -- Stop creating new walls timer.cancel(wallTimer) -- Update the highscore if score \> highscore then highscoreFile = io.open(system.pathForFile("highscore", system.DocumentsDirectory), "w") highscore = score highscoreFile:write("" .. score) highscoreFile:close() highscoreFile = nil end end elseif event.phase == "ended" and not isGameOver then if event.other.isSensor then score = score + 1 if score \> highscore then scoreLabel.text = "" .. score .. "!" else scoreLabel.text = "" .. score end playSound("score") end end end fbPost = function(event) local fbAppID = "xxxxxxxxxxxxxxxx" facebook.login( fbAppID, facebookListener, { "publish\_actions" } ) timer.performWithDelay(3000, facebook.request( "me/feed", "POST", { message="Hello Facebook" } ) ) -- end 

This is essentially the order in which I have my code in also. Just to note I recently added the time delay to Facebook post request because I thought maybe I wasn’t giving enough time between login and posting. Seems not to be the case.

*EDIT: I should also note that I was trying the “publish_stream” I can put “publish_actions” in the login also, and I get nothing. Same results.

I think you’re running into the same issue another person is having.  The facebook.* calls are asynchronous which means that the next statements execute right away and don’t wait on the facebook.* calls to complete.  Adding the 3 second delay is your attempt to solve that.  The only problem is that facebook.login() may take longer than 3 seconds to happen.  If it has to prompt the user for permission and such, that could be well longer than 3 seconds.

I would put the facebook.request() call inside the fblistener function inside of the “session” check:

local function facebookListener( event ) &nbsp; &nbsp; print( "event.name", event.name ) &nbsp;--"fbconnect" &nbsp; &nbsp; print( "event.type:", event.type ) --type is either "session", "request", or "dialog" &nbsp; &nbsp; print( "isError: " .. tostring( event.isError ) ) &nbsp; &nbsp; print( "didComplete: " .. tostring( event.didComplete ) ) &nbsp; &nbsp; print(event.response) &nbsp; &nbsp; --"session" events cover various login/logout events &nbsp; &nbsp; --"request" events handle calls to various Graph API calls &nbsp; &nbsp; --"dialog" events are standard popup boxes that can be displayed &nbsp; &nbsp; if ( "session" == event.type ) then &nbsp; &nbsp; &nbsp; &nbsp; --options are: "login", "loginFailed", "loginCancelled", or "logout" &nbsp; &nbsp; &nbsp; &nbsp; if ( "login" == event.phase ) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; local access\_token = event.token &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --code for tasks following a successful login &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; facebook.request( "me/feed", "POST", { message="Hello Facebook" } )&nbsp;&nbsp; \<----- HERE &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp;

You might also want to consider a flag that determines if you’re logged in or not.  If you’re logged in, then don’t call facebook.login() a 2nd time but call facebook.request() instead.

Rob