B4A Library Facebook SDK Wrapper + Native Facebook LoginButton

Periklis Koutsogiannis

Active Member
Licensed User
Introduction

This is my first contribution to the discovery of the decade (#b4a-rocks) so bear with me!

Facebook requires that native android mobile apps must use the facebook sdk in order to be able to be listed in its AppCenter. We could not find anything, so we wrote our own wrapper. It utilizes the SSO with fallback of the native facebook application and also wraps the native Facebook LoginButton widget through DesignerCustomView.
The great thing with the SDK (SSO) is that all access tokens are long-lived and the native Facebook app (500+ million installs) on the user's device will ensure that they will always stay fresh and updated.
Used SocialApi classes:
  • FacebookProvider: A non activity object that must be declared in any Sub Process_Globals.
  • FacebookLoginButton: A CustomView (extents FacebookProvider and implements DesignerCustomView) that can be used design-time.
  • SocialApiActivity: An activity object that can be only declared in a Sub Globals and is used to bind a FacebookProvider object to an activity through the FacebookProvider.SetActivity method.
Getting started
  1. Download the latest socialapi package, extract it anywhere on your hard disk and note the folder name.
  2. Copy the wrapper files (jar + xml) in the socialapi folder into your B4A Libraries folder.
  3. Each sample in the socialapi\facebook\samples folder has AdditionalRes and AdditionalJar directives that have to be changed. Change the C:\b4a-dev folder to where you have extracted the socialapi archive.
The samples archive contains:
  • Sample1: Full featured guide that contains 2 activities and 1 code module with 1 shared FacebookProvider instance.
  • Sample2: Simple connect with a native login button that can be used as a bare-bone template for your new apps
  • Sample3: Simple connect with a FacebookLoginButton
  • Sample4: Simple Album/Photo browser
Important: The samples work only when using an emulator because they are using facebook's SeesionLoginSample app details. If you want to run any of the samples on a real device, change its app_id and app_name with your own app details in AppConfig\Values\strings.xml and go to step 1 in the Set up our app in the Facebook Developer Dashboard section below.
Tip: Every HTTP request inside the library is driven by an AsyncTask followed by a Common.DoEvents while waiting for the task to complete. That means that you can safely wait for a result after a request without blocking your app and without the need of extra events.
B4X:
Sub BtnUpload_Click
    Facebook.PleaseWaitText = "Uploading large video ..." 'Set it to "" to omit a ProgressDialog
    Dim Result as FacebookResult = Facebook.UploadVideo(File.DirAssets, "very_large_video.mp4", "My wedding!")
    If Result = Null Then
        MsgBox("A previous request is pending.", "Error")
    Else
        If Result.Success Then
            MsgBox(Result.Map, "Success!")
        Else
            MsgBox(Result.Message, "Error")
        End If
    End if
End Sub
Step-by-step new app tutorial (based on Sample2)

1. Create a new folder in your app root folder named AppConfig\Values. In there, create a new file named strings.xml and add your facebook app details (app_name and app_id):
B4X:
<resources>
    <string name="app_id"><your_app_id></string>
    <string name="app_name"><your_app_name></string>
</resources>

2. Add following code to your manifest:
B4X:
AddApplicationText(
    <meta-data
        android:name="com.facebook.sdk.ApplicationId"
        android:value="@string/app_id"/>
    <activity
        android:name="com.facebook.LoginActivity"
        android:theme="@android:style/Theme.Translucent.NoTitleBar"
        android:label="@string/app_name"/>)

3. Add following directives to your project's main file:
B4X:
#AdditionalRes: ..\AppConfig

#AdditionalRes: <your-installation-folder>\socialapi\facebook\sdk\res
#AdditionalJar: <your-installation-folder>\socialapi\facebook\sdk\facebooksdk.jar

4. Select the SocialApi library from the list of the available libraries in the IDE. Declare a FacebookProvider and a SocialApiActivity object in Sub Process_Globals and Sub Globals respectively
B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

    Dim Facebook As FacebookProvider
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    Dim ThisActivity As SocialApiActivity
End Sub

5. Log app's unique HashKey in Sub Activity_Create because you will need this later. Then call the FacebookProvider.SetActivity method in your Sub Activity_Resume in order to bind the FacebookProvider instance to the current activity passing the name of the event that will be raised every time the facebook session changes.
B4X:
Sub Activity_Create
    Log(FB.HashKey)
End Sub

Sub Activity_Resume
    FB.SetActivity(ThisActivity.Initialize("facebook")) 'The event prefix
End Sub

6. Create the event handlers
B4X:
Sub Facebook_Event (Provider as SocialApiProvider)
    BtnConnect.Enabled = Not(Provider.Connected)
    BtnDisconnect.Enabled = Provider.Connected
End Sub

Sub Facebook_Connected (Provider as SocialApiProvider)
    Msgbox(Provider.Me, "!")
End Sub

Sub Facebook_Disconnected (Provider as SocialApiProvider)
    Msgbox("Bye bye!", "JustDisconnected!")
End Sub

Sub Facebook_Failed (Provider as SocialApiProvider)
    If Msgbox2("Failed to actualize your details."&CRLF&CRLF&"Retry?", "Error", "Yes", "No", "", Null) = DialogResponse.POSITIVE Then
        Provider.Retry
    End If
End Sub

7. Create the login/logout handlers. The login and logout actions are performed asynchronously
B4X:
Sub BtnConnect_Click
    Facebook.Login(Array As String (Facebook.Constants.Permissions.EMAIL))
End Sub

Sub BtnDisconnect_Click
    Facebook.Logout
End Sub

8. Do something and evaluate the result
B4X:
Sub BtnMe_Click
    Dim Result As FacebookResult = Facebook.GetMe("")
    If Result.Success Then
        Msgbox("UserID=" & Result.Map.Get("id") & CRLF & CRLF & Result.Map, "Success")
    Else
        Msgbox(Result.Message, "Error")
    End If
End Sub
Done! Now we have to setup our app in the Facebook Developer Dashboard.

Set up our app in the Facebook Developer Dashboard

1. Hit Run, switch back to the B4A IDE and copy your HashKey from logcat to the clipboard




2. (skip this if you already have an android platform) Go to you Facebook AppDashboard and switch to Settings




2. (skip this if you already have an android platform) Scroll down, hit "Add platform" and choose Android




3. Every Android app you'll create will be signed, and you will need to register each app's key hash with Facebook as a security check for authenticity. Each new app will have it's own hashkey. And if you compile the app on a different machine, you will have to change the hashkey again since it will be different.
Important: The hashkey is unique per app_id/private_sign_key/build_machine. Whenever any of these 3 factors changes, your hashkey will change as well and you will have to update it. You can use multiple hashkeys if you are building with different machines (multiple developers). Please read this first if you are planning to publish your app to the play store.
  • Key Hashes: Paste you HashKey that you previously copied from logcat
  • Single Sign On: Enable this setting.



Done! Log in with your app and start posting/uploading! :cool:


Useful links

Please test and post any feedback, questions, comments you may have!
That's all for now folks!~


Version history until SocialApi 2.3

2.3
  • Restructured again into a single package (socialapi) after finding out how to properly use the #AdditionalRes directive to avoid conflict with other b4a libraries
2.2
  • Restructured due to a conflict with AdMod library and FacebookProvider has its own package
2.1
  • Changed: GetPhotos, GetAlbums have an extra parameter UserId. Leave it blank to access your own profile.
2.0
  • Now part of the SocialApi unified wrapper library
  • Major code refactoring (again)
  • Renamed: Facebook -> FacebookProvider
  • Renamed: WrapperActivity -> SocialApiActivity
  • Renamed: WrapperActivity.Initialize -> SocialApiActivity.GetWithEvent
  • Added: FacebookProvider.GetAppFriends, FacebookProvider.GetFriends, FacebookProvider.GetTaggableFriends
1.6
  • Fix: Fixed a bug that prevented requests from being canceled properly.
  • Change: Complete code refactoring. Now using our SocialApiWrapper library that provides common functionality to our SDK wrappers
1.53
  • Added: Facebook.GetFeed,Facebook.GetComments, Facebook.GetComment, Facebook.GetLikes, Facebook.GetGraphObject, Facebook.DeleteGraphObject
1.52
  • Added: Facebook.JustDisconnected
1.51
  • Enhancement: Better upload progress representation
1.5
  • Added: Facebook.GetPhoto
  • All "please-wait" dialogs are now cancelable. If user cancels a progressdialog, Facebook.Result.Canceled will be true
  • Added: upload progress while uploading
  • Samples updated.
1.4
  • Removed: generic method Facebook.Request
  • Added: generic methods Facebook.Get, Facebook.Post, Facebook.Delete
  • Added: Facebook.CreateAlbum, Facebook.GetAlbums, Facebook.GetAlbum, Facebook.GetPhotos, Facebook.DeletePhoto
  • Added: extra parameter AlbumId (returned by Facebook.CreateAlbum and Facebook.GetAlbum) to Facebook.UploadPhoto. Set it to "" to upload to the app's default album
  • Samples updated.
1.3
  • Now, there is 1 zip file that contains all samples and the wrapper.
  • There is no need now to manually call Facebook.Me, since the logged-in user's details will be fetched automatically whenever the system gets an access token
  • The previously Facebook.Me Method is now a Map object, and there is a new Facebook.GetMe method instead
  • There is a new Facebook.JustConnected property that will be set once when connected and will ensure that Facebook.Me has all logged in user details.
  • Samples updated.
1.2
  • Fix: Fixed a Map generation issue that prevented access to Result.Map
1.1
  • Fix: Correctly handle uploads from Assets
    (now using anywheresoftware.b4a.objects.streams.File.OpenInput)
1.0
  • Initial version
 

Attachments

Last edited:

Periklis Koutsogiannis

Active Member
Licensed User
Update: 1.1

Updated files: facebook.zip

  • Fix: Correctly handle uploads from Assets (now using anywheresoftware.b4a.objects.streams.File.OpenInput)
 
Last edited:

Periklis Koutsogiannis

Active Member
Licensed User

Douglas Farias

Expert
Licensed User
the same
log = hl4hL2scpObNV3IWGAhhjQZ2lfI=
and same error this can is error on your app no ?
have this hash key on your app?
hl4hL2scpObNV3IWGAhhjQZ2lfI=
 

Periklis Koutsogiannis

Active Member
Licensed User
I noticed that when I am using an emulator, the samples work. On a real device I get the same error. My own app works in a real device without hashkey errors though.

Are you using an emulator or a real device?
 

Periklis Koutsogiannis

Active Member
Licensed User
If you are using a real device, the samples may not work. Only your own app will work as it appears.

Use an emulator to test the samples and please tell me if they work.
 
Top