How to Get Facebook Friends List in Java Servlet or JSP in 5 Easy Steps Using RestFB

Updated: July 9, 2014. (old post given below)

In the link that open Facebook Loging dialog, you need to specify one or more permissions that user must grant you, only then your applications can fetch associated data or performs a particular operation. If you do not specify any permission, default basic_info was used in API V1. In latest V2 API, the default is named to public_profile.

If you are developing a new Facebook App or your Facebook App was not active for last couple of months, the Facebook by default would use API 2.0 version to serve your requests that no more allows fetching all Facebook friends list with basic_info permission. (Reference) basic_info permission no more exist, it has been replaced with public_profile permission (the default) which contains same info except the friends list. The all login user friends list were earlier available under basic_info.

Another permission user_friends is introduced in version 2.0, but it do not return all friends of the login user under /me/friends endpoint (we would use from RestFB), but only those friends who are already using the app you are going to login. If you are new to fetching Facebook friends, more accurately we should call it, facebook friends who are using-app. Here I share some steps you need to follow:

1. Create an app at Facebook Apps. Make sure you have configured/noted following things:
  1. Go to https://developers.facebook.com/apps/ and choose Create a New App under Apps Tab.

  2. Note your App ID and App Secret, it would be used in our app code.

  3. As we are using Facebook Login from website, so under Settings->Basic tab, click Add Platform. and choose Website. Don't forget to input Contact Email (on same form), its mandatory. For my test app, my app page looks like this:

  4. Under left menu, choose Status & Review, and Activate App for general public clicking the right button labeled as NO, make it YES. so that anybody can use it to login at your website. See below image how it should look.

2. Create a login page with Facebook Login link. Its to open Facebook authentication dialog. Here is the link code in index.jsp, that contains this link.

<a href="https://graph.facebook.com/oauth/authorize?client_id=1524731954416948&scope=email,user_friends&redirect_uri=<%=URLEncoder.encode("http://localhost:8080/bitspedia-lab/FriendsListServlet")%>">Click Here to Login Using Facebook</a>

3. When user click on the link, it open the Facebook Authentication dialog.


4. After the Login window, Facebook would show the Authorization Box, its only displayed in case of permissions other than basic_profile are used. This window looks like:


5. After user allows the asked permissions. The Facebook would redirect the user browser to the link you provided above opening Login Dialog under redirect_uri. When Facebook redirect to provided redirect_uri, it also sends a parameters (as HTTP request parameter) with the name of code. We would use the code parameter is used to retrieve access_token. We would do so in FriendsListServlet.

6. Below code belongs to FriendsListServlet. It seems lengthy, but performs very simple task. The brief explanation is given after the code section.

package com.bitspedia.servlets;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.restfb.Connection;
import com.restfb.DefaultFacebookClient;
import com.restfb.FacebookClient;
import com.restfb.exception.FacebookException;
import com.restfb.types.User;

public class FriendsListServlet extends HttpServlet {
public static String APP_ID = "write your app id here ";
public static String APP_SECRET = "write your app secret here";
private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String code = request.getParameter("code");

String URLEncodedRedirectURI = URLEncoder.encode("http://localhost:8080/bitspedia-lab/FriendsListServlet");
String MY_ACCESS_TOKEN = "";

String authURL = "https://graph.facebook.com/oauth/access_token?" +
"client_id=" + FriendsListServlet.APP_ID + "&" +
"redirect_uri=" + URLEncodedRedirectURI + "&" +
"client_secret=" + FriendsListServlet.APP_SECRET + "&" +
"code=" + code;

URL url = new URL(authURL);

String result = readURL(url);
String[] pairs = result.split("&");

for (String pair : pairs) {

String[] kv = pair.split("=");
if (kv[0].equals("access_token")) {
MY_ACCESS_TOKEN = kv[1];
}
}

FacebookClient facebookClient = new DefaultFacebookClient(MY_ACCESS_TOKEN, FriendsListServlet.APP_SECRET);

Connection friends = null;

try {
User loginUser = facebookClient.fetchObject("me", User.class);
request.setAttribute("loginUser", loginUser);
friends = facebookClient.fetchConnection("/me/friends", User.class);

} catch (FacebookException e) {
e.printStackTrace();
}

List friendsList = friends.getData();
request.setAttribute("friendsList",friendsList);

getServletConfig().getServletContext().getRequestDispatcher("/FriendsList.jsp").forward(request, response);
}

private String readURL(URL url) throws IOException {

ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = url.openStream();

int r;

while ((r = is.read()) != -1) {
baos.write(r);
}

return new String(baos.toByteArray());

}
}

  1. code parameter is submitted to our servlet by Facebook. We have retrieved it from request in Line 28. It would be used later to fetch access_token. access_token is another alphanumeric long string that is used instantiate FacebookDefaultClient object (a RestFB Class). This client object would be actually use to make different API call to Facebook server.
  2. Facebook provides another URL to retrieve access_token, this URL is https://graph.facebook.com/oauth/access_token?, it receives a couple of parameters and returns access_token and time when this token would expire. These parameters are submitted to get access_token:
    1. client_id (this is APP ID)
    2. redirect_uri (it must be same as you used in dialog box, if different, the access_token would not be generated)
    3. client secret (this is APP Secret), to make sure only authorized persons could make API calls on behalf of an App. You should not share it with others.
    4. code, this is same code that was submitted to the Servlet.
  3. The readURL method in Line 41 actually makes the request to fetch access_token, it just returns the string that contains access_tokens and epires attributes.
  4. The format of the string return by readURL is access_token=CAAVq7RqWb&expires=5158143, now we need extract the access_token value from it. Line 41-50 does so.
  5. Line 52 instantiate DefaultFacebookClient object that takes access_token and APP Secret in it constructor. The DefaultFacebookClient object is used to make different API calls.
  6. Then we have retrieve the login user info and his list of friends who are using our app and stored it into request arguments, from where the JSP page would retrieve and display the content as output.
  7. Line 68 dispatch the request to view i.e. FriendsList.jsp

7. The JSP page output is as follows.


8. Here is the JSP code
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><br />
<!DOCTYPE html><br />
<html><br />
<head><br />
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><br />
<title>BitsPedia - Facebook Friends List</title><br />
</head><br />
<body><br />
<h1>Login User Information</h1><br />
<ul><br />
<li>User Facebook ID: <c:out value="${loginUser.id}" /></li><br />
<li>First Name: <c:out value="${loginUser.firstName}" /></li><br />
<li>Last Name: <c:out value="${loginUser.lastName}"/> </li><br />
</ul><br />
<h1>Friends List - Who are using the App</h1><br />
<table><br />
<c:forEach items="${friendsList}" var="user"><br />
<tr><br />
<td><c:out value="${user.name}" /></td><br />
<td><img src='https://graph.facebook.com/<c:out value="${user.id}"/>/picture' /><br />
</td><br />
</tr><br />
</c:forEach><br />
</table><br />
</body><br />
</html>

If you know even very little about JSP, you can see have just displayed some attributes of loginUser key we inserted into request as an attribute. Then I have iterated the friends list to display the name and picture of each friend.

You can Download Complete Source Code too.

Share your issues under comments, i would reply to address in this or new posts. 

=====================================================================
Old Post: (November 1, 2012)

Here we will see how to get Facebook friends list in just 5 steps:

1. Create a new Facebook App and write down its App ID (aka Client ID or API Key) and App Secret (aka Client Secret). Set Site URL = http://localhost:8080/facebookfriends

2. In your HTML or JSP page Make a hyperlink, to send user at Facebook Login page, like this:
Click Here

Complete source code is available:Click Here to view.

3. After successful authentication, Facebook will redirect user to the URL passed in step 2 under redirect_uri


4. When Facebook redirect the user, it sends a "code" parameter to our servlet, we can access this "code" like this: (request is HttpServletRequest object)
String code = request.getParameter("code");



5. The "code" and App Secret is passed to Facebook to get "access_token". Access Token is what we need to get friends list. This is how you can get "access_token":
String MY_ACCCESS_TOKEN;
String authURL = "https://graph.facebook.com/oauth/access_token?client_id=CLIENT_ID&redirect_uri=http://localhost:8080/facebookfriends/FriendsListServlet&client_secret=APP_SECRET&code=" + code ;
URL url = new URL(authURL);
String result = readURL(url);
String[] pairs = result.split("&");

for (String pair : pairs) {
String[] kv = pair.split("=");
if (kv[0].equals("access_token")) {
MY_ACCESS_TOKEN = kv[1];
}
} // end of for loop

// here is the readURL method
private String readURL(URL url) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = url.openStream();
int r;
while ((r = is.read()) != -1) {
baos.write(r);
}
return new String(baos.toByteArray());
}

Once you have the Access Token, getting friends lists is a matter of 2 lines of code:
FacebookClient facebookClient = new DefaultFacebookClient(MY_ACCESS_TOKEN);
Connection friends = facebookClient.fetchConnection("me/friends", User.class);
List friendsList = friends.getData();

//Lets display some friends info on console

for (User user : friendsList) {
System.out.println(user.getId() + " : " user.getName());
}

Don't forget to replace the CLIENT_ID and APP_SECRET in above code snippets (and attached sample project) with actual values you got in Step 1.


Here is the final output:



Comments

  1. Do u have a complete example somwhere for this ?

    ReplyDelete
  2. I don't find a complete example, I shared code snippets from my project I created about a year ago. I will attach complete code (in form of project) by this weeekend, with this article.

    ReplyDelete
  3. Working sample project created and attached.

    ReplyDelete
    Replies
    1. it's not downloading............plz help

      Delete
  4. hi i can follow your code but user's friend birthday value are null
    please tell me how to solve this problem
    I want access the user's Friend list with their Profile pics and birthday
    please reply immediately as well as possible.

    ReplyDelete
  5. (Blogger comments do not allow html tags, so I have replaced start tag with (tag) and end tag with (tag-end) ... little apologize for poor readability.)

    1. Facebook do not send friends birthdays' under default Scope. If you want to get friends birthdays, add "scope=friends_birthday" to URL that you hit on Facebook Connect button. e.g. (tag)a href="https://www.facebook.com/dialog/oauth?client_id=(tag)%=Settings.getFbAppId()%(tag-end)&redirect_uri=(tag)%=Settings.getHostAndContext()%(tag-end)/facebook-connect.action&scope=friends_birthday"(tag-end)Connect (tag)/a(tag-end)

    This way, the restFB will be able to fetch friends birthdays. Please note, when fetching the friends list, you again need to pass "birthday" field. e.g. Connection(tag)com.restfb.types.User(tag-end) userFriendsCon = facebookClient.fetchConnection("me/friends", com.restfb.types.User.class, Parameter.with("fields", "id, name, birthday"));

    Then you can get Birthday as String using: fbUser.getBirthday() (I tried -(tag-end) works perfect). If you need it as Date object, use fbUser.getBirthdayAsDate() -- it should work --- (restFB.jar 1.6.9). Please also note, you will get birthday of friends who have really shared with you. For others, it will return null.

    2. I need to check how to get profile picture URL from user object. But if you just want to display the picture at you webpage, you really don't need to get the pic URL. The Graph API will return on the fly. For example, in my JSP page, I can fetch the pic from Facebook server directly using: (tag)img src="https://graph.facebook.com/${fbUser.fbId}/picture"/(tag-end)

    Here fbId is just user ID that you already have in the friends collection returned by RestFB. This approach is also good because, you don't need to waste your memory to save a lot of pics and it will serve an updated picture always.

    Hope I answer your question, let me know if I can help you more.

    ReplyDelete
    Replies
    1. heloo
      thanks for reply..
      i want to adjust my code as per your instruction. Please check this one
      href="https://www.facebook.com/dialog/oauth?client_id=***********&redirect_uri=http://localhost:8888/bitsfriend/facebook-connect.action&scope=friends_birthday"/>Click Here
      and error are come like this

      HTTP ERROR 404
      Problem accessing /bitsfriend/facebook-connect.action. Reason:

      NOT_FOUND

      can you please guid me

      2> then i replace my code as per your instruction
      Connection friends = null;
      friends = facebookClient.fetchConnection("me/friends", com.restfb.types.User.class,Parameter.with("fields","id,name,birthday"));

      please check can i write correct code

      please reply immediately as well as possible.

      Delete
  6. Hmm, seems the action is missing or not mapped properly. You must create facebook-connect.action Or you can create a simple Servlet. Please see the attached files/project and tweak it as per your requirements. Please note, I am using Conventions Plugin of Struts 2, which magically maps the URL to action classes. It seems, you are not using that, in your lib folder. Please have a look how Conventions Plugin works, or simply put it into your lib to see magic.

    ReplyDelete
    Replies
    1. hi i use simple servlet and jsp.
      finally i got solution.
      thanks for replying my questions.
      I am newly handle Google app engine
      My next task is whatever i got list with pics save the datastore.
      So u have any idea regarding google app engine.
      I got a list with profile pics so how to store this list in datastore and access whole list
      again u have any solution please tell me.

      Delete
    2. can u please tell me how to access friends profile pics with their birthday's in calendar using simple code of jsp or javascript.
      please reply. i need any kind of solution.

      Delete
  7. Hi I really need your help I used your example and running it on my local machine. Works fine. Now I moved it to Google AppEngine and I get a java.lang.NullPointerException here:
    List friendsList = friends.getData();
    Explanation from App Engine: This request caused a new process to be started for your application, and thus caused your application code to be loaded for the first time. This request may thus take longer and use more CPU than a typical request for your application.

    ReplyDelete
  8. hii all of you....

    i am new and i am totally confused of that url which you passing and what is client id.
    when i click on that link "Click Here". i am getting some erroe ---
    " An error occurred with Reliable Rishtay Development. Please try again later "

    Please help me.

    ReplyDelete
  9. This comment has been removed by the author.

    ReplyDelete
  10. Hi friends,, Plz any one help me, 'In jsp page how to send and receive the comments from facebook'. (I'm working on struts application)

    ReplyDelete
  11. hi i am running this example but when i run in eclipse then it give me the error
    java.net.UnknownHostException: graph.facebook.com
    java.net.AbstractPlainSocketImpl.connect(Unknown Source)
    java.net.PlainSocketImpl.connect(Unknown Source)
    java.net.SocksSocketImpl.connect(Unknown Source)
    java.net.Socket.connect(Unknown Source)
    can any one help ?

    ReplyDelete
  12. I download your project and changed the application id and secret id.I execute this source code but i could not get value for parameter code.pls tell me how to get value?

    ReplyDelete
  13. how to get application id and secret id?

    ReplyDelete
  14. this complete code to be placed where means in which extension.........plz help

    ReplyDelete
  15. Source code link updated to Google Drive file.

    Please choose File->Download to download compressed file.

    ReplyDelete
  16. there are lot of files attached with it.....where to place these all files and how to run these files ??????
    please help......

    ReplyDelete
  17. Great Thinking Friend.........

    ReplyDelete
  18. This comment has been removed by the author.

    ReplyDelete
  19. I am getting error like this

    Given URL is not allowed by the Application configuration.: One or more of the given URLs is not allowed by the App's settings. It must match the Website URL or Canvas URL, or the domain must be a subdomain of one of the App's domains.

    ReplyDelete
    Replies
    1. Goto your FaceBook Summary Page. The link as follows,

      https://developers.facebook.com/apps/{Your App Id}/summary

      Find the labels{App Domain & SiteUrl). Enter the Value as follows,

      App Domains: localhost
      Site URL: http://localhost:8080/facebookfriends/FriendsListServlet

      Save the Changes.. Wait for 5 min.. Run the Sample Code.. It will work..

      Delete
  20. Good Stuff Mr.Asif Shahzad.. Thanks a Lot....

    ReplyDelete
  21. Hi Asif Shahzad,

    Can u please guide me for getting User Details using your Sample Code?

    ReplyDelete
  22. Hi To all,
    i have access token ,can i get friends list using that access token.
    please help me.
    thanks in advance

    ReplyDelete
  23. Hi there, thanks a lot for your tutorial. It was very helpful for me to start with RestFB. I am writing a server application using Jave EE and I would like to post on the user's wall without the need to log in or ask for the user's permission every time doing so. I also need to access most of the user's facebook data. Perfect would be if the user just have to give the application once permission. Is that possible using your example? Many thanks. Best

    ReplyDelete
  24. Thanks for giving me information about my problem. I was searching the NET and here I found. Also if you want more work just click
    Mp3Raid UK proxy

    ReplyDelete
  25. I am not getting correct count of friends list.. Can you tell me what is the problem?

    ReplyDelete
  26. How can I download the facebook user profile photo using java?

    ReplyDelete
  27. getting error :Connection refused: connect

    ReplyDelete
  28. Read updated post above, I have discussed some issues and shared new code sample.

    ReplyDelete
  29. This comment has been removed by the author.

    ReplyDelete
  30. friends = facebookClient.fetchConnection("me/friends", User.class);

    in the above line doesn't fetch the friends list

    after executing the program friends string is empty how to solve this

    ReplyDelete
  31. Thank you,
    But i don't receive anything but an empty friends list!
    what could be the problem?

    ReplyDelete

Post a Comment