Tutoriais

Working with the Facebook API in a Cordova App — SitePoint – SitePoint

In this tutorial we’ll be creating a Cordova app that connects to the Facebook API using the official Facebook

In this tutorial we’ll be creating a Cordova app that connects to the Facebook API using the official Facebook plugin for Cordova. We’ll cover how to login and logout of Facebook, use dialogs, and make calls to the Graph API. Note that this tutorial isn’t for beginners, I will assume that you have already setup your machine to work with Cordova and deploy to an Android device.
First create an app on the Facebook Developer Website. Hover over the My Apps menu and select add a new app. This will open a modal window that allows you to select the platform for your app. In this case we’ll be deploying to an Android device so select Android from the modal window.
new facebook app
Enter a name for the app and click the Create New Facebook App ID button.
new facebook ID
This will ask you if the app is a test version of an existing app, leave it on the no default. The other option is the category, select apps for pages then click on the create app ID button.
app category
Next you will be asked to add the Facebook SDK to your project. We don’t need to do this for our app so keep scrolling down until you find the Tell us about your Android project section. Enter com.yourname.appname for the package name and then com.yourname.appname.MainActivity for the default activity class name, replacing with appropriate values for your project.
project details
Once that’s complete we need to add the development and release key hashes. These validate the authenticity of your app so that Facebook is sure you are the author of the app and requests made to their API are from you.
development hashes
Before you can generate a hash, you first need a keystore. You can generate one by executing the following command in a terminal window.
Get the hash from the keystore:
This should ask you for a password. Just use the same password used when you created the keystore. Once entered it should return the hash for that keystore. Copy and paste it in the development hashes field.
Click next and refresh the page. Your app should now be listed when you click on the My Apps menu. Note the App ID as we will be needing it later when we install the Facebook plugin.
Now we’re ready to build the app. Install Ionic (which we will use for creating our app) with the following command:
Create a new blank app:
Add the android platform:
Next we need to install the following plugins:
Allows us to control which domains the app can make requests to.
Allows us to use the device camera to capture photos.
Allows us to upload photos captured by the camera plugin to a remote server.
Note: We’re using the old version of this plugin since the latest version is incompatible with the current Cordova version (5.0.0) at the time of writing. If you’re reading this in the future you might want to try using the following command: cordova plugin add cordova-plugin-file-transfer and see if it works for you. Otherwise use the command below.
The official Facebook plugin used for performing different operations with the Facebook API.
Install the plugins with the following commands:
Once that’s complete we need to install a front-end dependency called Angular Local Storage. This allows us to work with the local storage for caching data in our app. You can install Angular Local Storage through Bower with the following command:
Ionic installs Bower components in the www/lib directory. You can check the save location by opening the .bowerrc file in the root directory of the project.
At this point we’ll be primarily working inside the www directory. Open the index.html file in that directory.
Link to the Angular Local Storage script below the ionic.bundle.js file.
Below the app.js file link the following scripts:
Later I’ll explain what each of those scripts does. The service scripts are for making HTTP requests and as a wrapper for the Camera plugin. The controller scripts are for the different pages in the app.
Modify the <body> tag (and its contents) to have the following markup. <ion-nav-view> is where the different pages will be loaded later.
Open the www/js/app.js file and add the LocalStorageModule. This allows us to use the localStorageService for storing and retrieving data from the local storage.
Below the .run method, add the app configuration by calling the config method. This method accepts a callback function where we pass in the $stateProvider and $urlRouterProvider so that we can specify the route for the different pages in the app.
Breaking the code down. First we have an abstract state called app. This is like the parent state where all the other states defined below inherits from it. In this case we’re setting the templateUrl to templates/menu.html which is the path to the main template in which all the views will inherit from.
Create the main template under the www/templates directory and name it menu.html, adding the following.
This template uses <ion-side-menus> which displays a side menu on the left side of the app. By default it’s collapsed which shows a burger menu.
The <ion-nav-view> displays the current view. The name attribute must be specified because this is where the view is tied to.
The main content of this template is a list of menu items which links to the different pages in the app.
Returning to the www/js/app.js file, we then define the states for the different pages. These states all use the abstract state declared earlier. This is indicated by prefixing each route with app.. The url is the URL in which the view is displayed. For the login route we’ve only specified /login. But since we’re using an abstract state, the actual URL will be /app/login since the value for the url assigned earlier to the abstract state is /app. Then we have the views object in which we specify the name of the view where the template is displayed. This requires the templateUrl property which contains the path to the template. The same pattern is used in all the other routes.
Finally we specify the default page:
We’re using services as a container for the tasks needed to perform more than once throughout the app. This way we can avoid repeating the same code.
The first service that is the CameraService, this serves as a container for the API calls we can make with the Camera plugin. Create a CameraService.js file under the js/controllers directory and add the following.
Breaking the code down, we first wrap everything inside an ‘Immediately Executed Function Expression’. This prevents conflict with other scripts.
Next we specify the module to which this service belongs and that this service depends on Angular’s $q service. This allows us to run functions asynchronously.
This is then passed as an argument to the CameraService function.
Inside the function we set the me variable as an alias to the current context and use it to set the options for the camera plugin.
Next we have the getPicture function. This is the function called every time we need to take a photo. This returns a promise which means that we can use the then method to pass a function that we want to execute once the user selects the photo.
The Requests Service makes HTTP requests to the app server. The app that we’re building has a server component which allows us to inspect the response returned by the Facebook API and upload photos to the server. Create a RequestService.js file inside the js/services directory and add the following:
Breaking the code down, we first import several services built-in to Angular and Ionic.
Set the settings for the base URL for making requests and timeouts:
The requestTimeout function allows us to alert the user when a request reaches the timeout value specified. This works by stopping the timeout once we get a response from the request.
The sendData function allows us to send data to the server. For this app we’re using it to send user data to the server and then save it to the database. This function accepts the data sent as its parameter and then uses Angular’s $http service to make a POST request to the server. Once we get a success as a response, we cancel the timeout so the call to the $ionicPopup.alert doesn’t get executed. As with other functions we’re using the $q service to turn it to an asynchronous function call. Later when we begin calling these functions from the controller you will see a lot of then() method calls triggered whenever we call deferred.resolve(response). We can then pass a function to the then() method in which we can have access to the response returned from the request.
The uploadPhoto function allows us to upload photos to the server. This accepts the photo_url which is basically the FILE_URI returned by the camera plugin after a photo has been taken. The params contains any custom data that we want to pass in with regards to the file.
The controllers are mainly used for listening to events and responding to them. An example is when a user clicks on a button. The controller is responsible for handling that specific event.
The login controller handles all the events that happen on the login page of the app. Create a LoginController.js file under the js/controllers directory and add the following:
Just like the services, we can import services inside controllers. This time we’re using two new services: $scope and localStorageService.
Here’s a brief description of what they do:
Inside the controller we’re attaching the updateLoginStatus function. This function checks if the current Facebook session is still active through the facebookConnectPlugin object available globally from the Facebook plugin. We then update the value of the logged_in property based on the result. This flips the switch in the view on whether to display the login or the logout button.
Attach the fbLogin function to the current scope. This gets executed when the user clicks on the login button.
Inside the fbLogin function we call the login method from the facebookConnectPlugin object, opening the Facebook login box. If the Facebook app is installed and a user is currently logged in, all the user has to do is to agree to the app permissions to authenticate the app. In this case the permission passed is email. This means the app will have access to the users email address. Once the user agrees to the permissions, the success callback function is called, otherwise the error callback function is called. When the user agrees, the response contains the user data. We use the localStorageService to save those in local storage and then use the RequestsService to send it to the server.
Here’s how the login will look:
facebook login
The fbLogout function is used to log out of Facebook. This destroys the current user session.
Next we can now add the login view. Views are saved under the templates directory. Create a login.html file inside that directory and add the following.
All views start with the <ion-view> tag. In the code above we’re passing in the title (shown in the page header) and the controller which this view uses. The ng-init directive executes the updateLoginStatus once this view is initialized. This means that it immediately gets executed when the user navigates to the login page.
The <ion-content> specifies the page content. In this case all we need is the button for logging in with Facebook. We added an ng-click attribute to this button and specify the fbLogin function defined earlier in the loginController as the value. ng-click is a directive built-in to Angular which is primarily used for listening to click events in a specific element. This means that when the button is clicked it executes the fbLogin function, the same is true with the button used for logging out of Facebook. The ng-hide and ng-show directive hides and shows these two buttons depending on whether the user is logged in or not.
The UserDetailsController displays the info of the logged in user. Create a UserDetailsController.js file under the www/js directory and add the following.
Inside the controller we set the user to null so user info only shows when the button is clicked, calling the getUserInfo function.
Inside the function we get the Facebook user ID from local storage.
And use it for getting the user info from the Graph API. We’re only trying to get basic information available without app registration through the API.
To make a request to the Graph API, call the api method and pass four arguments. First is the path in which the request is made. Since we’re working with user data we’re using the users’s Facebook ID as the base and specifying which information we want to get by supplying fields as the query parameter.
We then pass a comma-separated list of all the fields we want to get. If you want a full list of the fields available, check out the Facebook Graph API User Reference.
The second argument is an array containing the different permissions the user needs to approve. Here we’re requiring the users public_profile and email. You can see a full list of the permissions in the Permissions Reference Page. Note that if a specific permission says that it requires a review from Facebook then you cannot use it even if you’re the developer of the app.
The third and fourth arguments are the success and error callbacks. If we get a success we issue an alert so we can see the response, send it to the server and assign the response to the user variable. In the user details view this user variable is checked for existence and if it exists display the user data.
Here’s the user details view (www/templates/user-details.html). You can see that we have used the ng-if directive to check if the user variable is set. If it is then the user details are displayed.
Here’s how the user details page should look:
user details
The DialogController handles events in pages that use the Facebook sharing dialogs such as the feed, send and share dialog. Create a DialogController.js under the js/controllers directory and add the following.
Breaking the code down, inside the controller is the URL for accepting photo uploads. This is where the RequestsService submits the captured photo.
Next we have the postStatus function called when the user clicks on the button for posting a Facebook status.
Instead of posting directly using the graph API we use Facebook’s feed dialog. This requires an object containing the type of dialog, the URL to include in the post and the text to show as the title.
Call the showDialog method and pass dialog_options as the first argument. The second and third arguments are the success and error callbacks. The success callback gets executed if the user actually publishes the post. The error callback gets executed if the user cancels.
Here’s how posting the status should look in the app:
posting status
Attach the function for opening the default camera app in the device to the $scope. This uses the CameraService to trigger the camera app to open. Once the user finishes taking a photo, it assigns the local path of the photo to the photo property of the controller. This displays the actual image. Later this value is used by the function for posting the photo.
Next is the method for posting the photo.
Inside we add the options for the Facebook dialog. We’re using the feed dialog again but this time adding other options such as the name (name of the link attachment), caption (the text that appears below the link name), and description (appears below the caption text).
Create an object which stores the data submitted along with the photo. In this case we only need the caption inputted by the user.
Make an HTTP request to upload the photo to the server. Note that this is the server used by the app for uploading photos and inspecting responses, not Facebook’s servers. This is because we’re using the Facebook feed dialog which cannot directly accept uploads. All it can do is accept the URL to an image and add it as a link to a post. This means that what we’re simply linking to an image. The server returns the file name to the uploaded photo and we’re using that as the value for the picture attribute of the dialog.
Once we have that, we call showDialog to open another Facebook dialog which links to the photo uploaded.
Here’s how posting a photo looks:
posting photo
Lastly for the DialogController we have the sendMessage method which opens Facebook’s send dialog and we pass the URL that the user inputted. The send dialog then creates a preview for that URL and allows the user to choose whom to send it to and an optional text message.
Here’s how sending of messages should look:
sending message
The DialogController is used in these three views:
– the view for posting status
– the view for posting a photo
– the view for sending a message
The view for posting status (www/templates/post-status.html) accepts the values for the URL and caption of the status to post. Clicking on the Post Status button opens Facebook’s feed dialog.
The view for sending message (www/templates/send-message.html) accepts the URL that the user wants to share. Clicking on the Send Message button opens Facebook’s send dialog.
The view for posting photos (www/templates/post-photo.html) contains the button for capturing photos. As we saw in DialogController, this opens the default camera app on the device. Once a photo has been taken it is displayed inside the #photo-container div along with a text field that asks the user for the caption. Clicking Post Photo opens the feed dialog which displays a preview of the post.
Throughout the whole app we have been making requests to a server but we haven’t built it yet. In this section I’ll create the server component of the app so that we can complete it.
Before we proceed with the code, we need to install the following dependencies:
To install the dependencies, create a folder called server in the root directory of the app. Here we will save the files used by the server. Inside the folder create a package.json file and add the following:
Save the file and execute npm install to install the dependencies.
Create an app-server.js file and add the following:
Here we first import all dependencies and set their default options. For multer we’re setting the uploads folder to public/uploads. Create that folder and set the necessary permissions, for example:
Set the app to use the body-parser library.
Set the public folder as the static directory for express. If a file called myphoto.png is uploaded to the public/uploads directory, it is accessible through the following URL: http://your-server.com/uploads/myphoto.png
Attach the app to port 3000. This allows access at http://localhost:3000.
Define the route for the home page. We’re only using it for testing so you can check if the server is running.
Define the route for accepting data submitted from the app. The route logs that a request has been received and the contents of the request body. Then it returns an ‘ok’ as the response.
Finally we have the route for accepting uploaded files. This uses the upload object provided by the multer library to upload a single file. Once the file is uploaded, the file data is available in the req.file object and we send back the file name to the app.
Now we’re ready to compile the app and deploy to an Android device. Before we do, we need to run the node server and make it accessible through the internet.
Use ngrok to expose it to the internet:
This returns the URL which you can use in the app. Open js/services/RequestsService.js and update base_url. In js/controllers/DialogController.js update base_uploads_url.
Compile and run the app for Android:
That’s it! In this tutorial you’ve learned how to work with the Facebook API inside a Cordova app. Specifically you’ve learned how to log in and out of Facebook, use the Graph API to get users data and Facebook dialogs to post a status and send messages. You can access the source code used in this tutorial in this Github repo and I would love to hear any comments or questions you may have.
Wern is a web developer from the Philippines. He loves building things for the web and sharing the things he has learned by writing in his blog. When he’s not coding or learning something new, he enjoys watching anime and playing video games.
© 2000 – 2024 SitePoint Pty. Ltd.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

source

About Author

4tune