How to use the Facebook Graph Api Cursor-based Pagination

后端 未结 5 2328
南旧
南旧 2021-02-13 10:15

I didn\'t find any help on this topic. The Docs say

Cursor-based pagination is the most efficient method of paging and should always be used where possibl

相关标签:
5条回答
  • 2021-02-13 10:33

    I use this code:

    final String[] afterString = {""}; 
    final Boolean[] noData = {true};
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
    
    do{
       GraphRequest request = GraphRequest.newGraphPathRequest(
                AccessToken.getCurrentAccessToken(),
                "/me/likes",
                new GraphRequest.Callback() {
                    @Override
                    public void onCompleted(GraphResponse response) {
                        // Insert your code here
                        JSONObject jsonObject = response.getJSONObject();
                        try{
                            if(jsonObject.length() > 1) {
    
                                JSONObject jsonFacebook = (JSONObject) new JSONTokener(jsonObject.toString()).nextValue();
                                JSONObject likes_paging = (JSONObject) new JSONTokener(jsonFacebook.getJSONObject("paging").toString()).nextValue();
    
                                ArrayList<String> likes = new ArrayList<String>();
                                for (int i = 0; i < jsonFacebook.getJSONArray("data").length(); i++) {
                                    likes.add(jsonFacebook.getJSONArray("data").getJSONObject(i).getString("name"));
                                }
                                afterString[0] = (String) likes_paging.getJSONObject("cursors").get("after");
    
                            }else{
                                noData[0] = false;
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                });
    
        Bundle parameters = new Bundle();
        parameters.putString("pretty", "0");
        parameters.putString("limit", "100");
        parameters.putString("after", afterString[0]);
        request.setParameters(parameters);
        request.executeAndWait();
    }while(noData[0] == true);
    
    0 讨论(0)
  • 2021-02-13 10:40

    What I did in my project is basically doing the first call in onSearchClicked() and getting result in onCompleted() callback in ViewModel. If nextRequest is null, I return the list of results back to my fragment, if not, I do the next call, until the end is reached (nextRequest == null). Then, the accumulated list is returned to the fragment.

    class SearchViewModel() : GraphRequest.Callback {
    
        private var allPlaces = arrayListOf<FacebookPlace>()
    
        fun onSearchClicked(location: Location) {
          val request = GraphRequest.newGraphPathRequest(accessToken, "/search", this)
          request.parameters = parameters
          request.executeAsync()
        }
    
        override fun onCompleted(response: GraphResponse?) {
          if (response != null) {
            allPlaces.addAll(response.data)
    
            val nextRequest = response.getRequestForPagedResults(GraphResponse.PagingDirection.NEXT)
            if (nextRequest == null) {
                uiEvent.value = ShowPlaces(allPlaces)
            } else {
                nextRequest.callback = this
                nextRequest.executeAsync()
            }
        } else {
            Log.e(TAG, "Search response is null.")
        }
    }
    
    0 讨论(0)
  • 2021-02-13 10:48

    Though it's true that you should use GraphResponse.getRequestForPagedResults(), you can't use executeAndWait() unless you run it in a different thread.

    You can make it even easier using executeAsync().

    To get the first set of results:

        new GraphRequest(AccessToken.getCurrentAccessToken(),
                "/" + facebookID + "/invitable_friends",
                null,
                HttpMethod.GET,
                new GraphRequest.Callback() {
                    public void onCompleted(GraphResponse response) {
                        //your code
    
                        //save the last GraphResponse you received
                        lastGraphResponse = response;
                    }
                }
        ).executeAsync();
    

    Use that lastGraphResponse to get the next set of results:

        GraphRequest nextResultsRequests = lastGraphResponse.getRequestForPagedResults(GraphResponse.PagingDirection.NEXT);
        if (nextResultsRequests != null) {
            nextResultsRequests.setCallback(new GraphRequest.Callback() {
                @Override
                public void onCompleted(GraphResponse response) {
                    //your code
    
                    //save the last GraphResponse you received
                    lastGraphResponse = response;
                }
            });
            nextResultsRequests.executeAsync();
        }
    

    You can merge all that in a single method!

    0 讨论(0)
  • 2021-02-13 10:54

    I figured out a good way to traverse through facebook graph api pages using cursor pagination

        final String[] afterString = {""};  // will contain the next page cursor
        final Boolean[] noData = {false};   // stop when there is no after cursor 
        do {
            Bundle params = new Bundle();
            params.putString("after", afterString[0]);
            new GraphRequest(
                    accessToken,
                    personId + "/likes",
                    params,
                    HttpMethod.GET,
                    new GraphRequest.Callback() {
                        @Override
                        public void onCompleted(GraphResponse graphResponse) {
                            JSONObject jsonObject = graphResponse.getJSONObject(); 
                            try {
                                JSONArray jsonArray = jsonObject.getJSONArray("data");
    
                                //  your code 
    
    
                                if(!jsonObject.isNull("paging")) {
                                    JSONObject paging = jsonObject.getJSONObject("paging");
                                    JSONObject cursors = paging.getJSONObject("cursors");
                                    if (!cursors.isNull("after"))
                                        afterString[0] = cursors.getString("after");
                                    else
                                        noData[0] = true;
                                }
                                else
                                    noData[0] = true;
                            } catch (JSONException e) {
                                e.printStackTrace(); 
                            }
                        }
                    }
            ).executeAndWait();
        }
        while(!noData[0] == true);
    
    0 讨论(0)
  • 2021-02-13 10:58

    Do not reinvent the wheel.

    GraphResponse class already has a convenient method for paging. GraphResponse.getRequestForPagedResults() returns GraphRequest object, and you can use that object for paging.

    Also I found code snippet from facebook-android-sdk's unit test code.

    GraphRequest nextRequest = response.getRequestForPagedResults(GraphResponse.PagingDirection.NEXT);
    nextRequest.setCallback(request.getCallback());
    response = nextRequest.executeAndWait();
    
    0 讨论(0)
提交回复
热议问题