Search code examples
androidfacebookfacebook-graph-apifacebook-android-sdk

Save information in Graph Request response


Good Day,

I would like to save the information in a List<String> the values that I get from Graph Request but when I return the list, its empty. Can someone help me why?

    private List<String> getFriends(AccessToken accessToken) {
     List<String> friendsName = new ArrayList<String>();
    GraphRequest requestt =
            new GraphRequest(
                    accessToken,
                    "/me/taggable_friends",
                    null,
                    HttpMethod.GET,
                    new GraphRequest.Callback() {
                      public void onCompleted(GraphResponse response) {
                        JSONObject obj = response.getJSONObject();
                        JSONArray arr;
                        try {
                          arr = obj.getJSONArray("data");
                            for (int l=0; l < arr.length(); l++) {
                                JSONObject oneByOne = arr.getJSONObject(l);
                                System.out.println(oneByOne.opt("name").toString());
                                friendsName.add(oneByOne.opt("name").toString()); 

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

    Bundle parameters = new Bundle();
    parameters.putString("fields", "name");
    requestt.setParameters(parameters);
    requestt.executeAsync();
     return friends;
  }

Solution

  • You execute the request asynchronously. It means that the request will not be executed immediately after requestt.executeAsync(); but at some near point of future. That is why you are setting up the callback in the constructor. You should handle your friendsList in onCompleted callback instead of returning it in getFriends.

    You can change the getFriends method to take GraphRequest.Callback as second parameter and make it return nothing. So it would look more or less like this:

    public void getFriends(AccessToken token, GraphRequest.Callback callback) {
        GraphRequest requestt = new GraphRequest(token, "/me/taggable_friends",
                                                 null, HttpMethod.GET, callback);
        Bundle parameters = new Bundle();
        parameters.putString("fields", "name");
        requestt.setParameters(parameters);
        requestt.executeAsync();
    }
    

    And then you can call it like this:

    getFriends(accessToken, new GraphRequest.Callback() {
                  public void onCompleted(GraphResponse response) {
                    List<String> friendsName = new ArrayList<String>();
                    JSONObject obj = response.getJSONObject();
                    JSONArray arr;
                    try {
                      arr = obj.getJSONArray("data");
                        for (int l=0; l < arr.length(); l++) {
                            JSONObject oneByOne = arr.getJSONObject(l);
                            System.out.println(oneByOne.opt("name").toString());
                            friendsName.add(oneByOne.opt("name").toString()); 
                        }
                        //CONSUME YOUR FRIENDS LIST HERE
                    } catch (JSONException e) {
                      e.printStackTrace();
                    }
                  }
                }
        );
    

    It would be a good idea to rename your getFriends method to getFriendsAsync

    The better idea would be to create your own, more specified callback.

    public interface FacebookFriendsCallback {
        void onFriendsReceived(List<String> friendsNames);
    }
    

    And use it like that:

    public void getFriends(AccessToken token, FacebookFriendsCallback callback) {
        List<String> friendsName = new ArrayList<String>();
        GraphRequest requestt =
            new GraphRequest(
                accessToken,
                "/me/taggable_friends",
                null,
                HttpMethod.GET,
                new GraphRequest.Callback() {
                  public void onCompleted(GraphResponse response) {
                    JSONObject obj = response.getJSONObject();
                    JSONArray arr;
                    try {
                      arr = obj.getJSONArray("data");
                        for (int l=0; l < arr.length(); l++) {
                            JSONObject oneByOne = arr.getJSONObject(l);
                            System.out.println(oneByOne.opt("name").toString());
                            friendsName.add(oneByOne.opt("name").toString()); 
    
                        }
                        callback.onFriendsReceived(friendsName);
                    } catch (JSONException e) {
                      e.printStackTrace();
                    }
                  }
                }
        );
        Bundle parameters = new Bundle();
        parameters.putString("fields", "name");
        requestt.setParameters(parameters);
        requestt.executeAsync();
    }
    

    And then call getFriends method:

    getFriends(accessToken, new FacebookFriendsCallback() {
        public void onFriendsReceived(List<String> friendsNames) {
            //consume list here
        }
    }
    

    NOTE: this is not a tested, ready to copy-paste code. Rather the idea for your own implementation. Also some error handling would be needed.