简体   繁体   English

Facebook Graph API Pagination如何工作以及如何使用它迭代facebook用户提要?

[英]How does Facebook Graph API Pagination works and how to iterate facebook user feed with it?

I have a facebook Graph API call to get a facebook users feed: 我有一个facebook Graph API调用来获取Facebook用户提要:

dynamic myFeed = await fb.GetTaskAsync(
                    ("me/feed?fields=id,from {{id, name, picture{{url}} }},story,picture,link,name,description," +
                    "message,type,created_time,likes,comments")
                    .GraphAPICall(appsecret_proof));

The above returns a number of the latest user posts in a while say 21 or maybe 22 posts but not the complete list of user posts. 以上返回了一些最新的用户帖子,其中包括21个或22个帖子,但不是完整的用户帖子列表。 I searched for a way to iterate through a users feed using facebook pagination and I ended up finding this solution which works with facebook Offset pagination. 我搜索了一种使用facebook分页迭代用户提要的方法,我最终找到了适用于facebook Offset分页的解决方案。

dynamic myFeed = await fb.GetTaskAsync(
                    ("me/feed?fields=id,from {{id, name, picture{{url}} }},story,picture,link,name,description," +
                    "message,type,created_time,likes,comments")
                    .GraphAPICall(appsecret_proof), new {limit = "1000", offset = "21" });

This has taken me a step nearer to what I want to achieve but I think this is not the ideal way to do it and also it does not return all of users posts. 这让我更接近我想要实现的目标,但我认为这不是理想的做法,也不会返回所有用户帖子。 Is there any workaround? 有没有解决方法? Please help. 请帮忙。

PS: I am using Facebook C# SDK. PS:我正在使用Facebook C#SDK。

UPDATE1: As per Jeremy's answer. 更新1:根据杰里米的回答。 It seems that the facebook cursor pagination is the only right option for my requirements. 似乎facebook光标分页是我的要求唯一正确的选项。 I would like to know if C# facebook sdk provides any feature to iterate over the Next Edges so I can get all feed posts in one call, Is there any possible solution to this? 我想知道C#facebook sdk是否提供任何功能来迭代下一个边缘,这样我就可以在一个电话中获得所有的帖子,这有什么可能的解决方案吗? PS: I've been through facebook API docs many times and I know what exactly the Nodes, Edges and Fields are, the only unfortunate thing is that facebook doesn't support C# SDK as yet and I was unable to find a proper documentation on Facebook C# SDK too. PS:我已经多次通过facebook API文档,我知道Nodes,Edges和Fields到底是什么,唯一不幸的是facebook还不支持C#SDK,我无法找到适当的文档Facebook C#SDK也是。

First up a bit of terminology: 首先是一些术语:

nodes - basically "things" such as a User, a Photo, a Page, a Comment 节点 - 基本上是“事物”,例如用户,照片,页面,评论
edges - the connections between "things", such as a Page's Photos, or a Photo's Comments 边缘 - “事物”之间的联系,例如Page's Photos或Photo's Comments
fields - info about those "things", such as a person's birthday, or the name of a Page 字段 - 有关这些“事物”的信息,例如某人的生日或页面的名称

When you make an API request to a node or edge, you usually don't receive all of the results of that request in a single response. 当您向节点或边缘发出API请求时,通常不会在单个响应中收到该请求的所有结果。 This is because some responses could contain thousands of objects so most responses are paginated by default. 这是因为某些响应可能包含数千个对象,因此默认情况下大多数响应都是分页的。

To get all posts by a user you have 3 options: 要获得用户的所有帖子,您有3个选项:


Cursor-based Pagination 基于游标的分页

Cursor-based pagination is the most efficient method of paging and should always be used where possible. 基于游标的分页是最有效的分页方法,应尽可能使用。 A cursor refers to a random string of characters which marks a specific item in a list of data. 游标是指随机字符串,用于标记数据列表中的特定项目。 Unless this item is deleted, the cursor will always point to the same part of the list, but will be invalidated if an item is removed. 除非删除此项,否则光标将始终指向列表的同一部分,但如果删除项,则无效。 Therefore, your app shouldn't store any older cursors or assume that they will still be valid. 因此,您的应用不应存储任何旧游标或假设它们仍然有效。

When reading an edge that supports cursor pagination, you will see the following JSON response: 在读取支持光标分页的边时,您将看到以下JSON响应:

{
  "data": [
     ... Endpoint data is here
  ],
  "paging": {
    "cursors": {
      "after": "MTAxNTExOTQ1MjAwNzI5NDE=",
      "before": "NDMyNzQyODI3OTQw"
    },
    "previous": "https://graph.facebook.com/me/albums?limit=25&before=NDMyNzQyODI3OTQw"
    "next": "https://graph.facebook.com/me/albums?limit=25&after=MTAxNTExOTQ1MjAwNzI5NDE="
  }
}

To get all posts by a user you keep surfing the "next" edges (upserting new items). 要获得用户的所有帖子,您可以继续浏览“下一个”边缘(插入新项目)。 This is how I do it when I dump entire groups into RDBMS's for statistical analysis. 当我将整个组转储到RDBMS进行统计分析时,我就是这样做的。 Often you will see edges with nodes you have already encountered, that's why I mention to UPSERT (update if it exists otherwise insert). 通常你会看到你已经遇到的节点的边缘,这就是我提到UPSERT的原因(如果存在则更新,否则插入)。

Time-based Pagination 基于时间的分页

Time pagination is used to navigate through results data using Unix timestamps which point to specific times in a list of data. 时间分页用于使用指向数据列表中特定时间的Unix时间戳来浏览结果数据。

When using an endpoint that uses time-based pagination, you will see the following JSON response: 使用使用基于时间的分页的端点时,您将看到以下JSON响应:

{
  "data": [
     ... Endpoint data is here
  ],
  "paging": {
    "previous": "https://graph.facebook.com/me/feed?limit=25&since=1364849754",
    "next": "https://graph.facebook.com/me/feed?limit=25&until=1364587774"
  }
}

To get all a users posts you keep iterating back in time. 要获得所有用户帖子,请不断回顾。 This method will get you the posts in order, although may want them returned in an order by FaceBooks edge algorithm. 此方法将按顺序为您提供帖子,但可能希望它们通过FaceBooks边缘算法按顺序返回。

Offset-based Pagination 基于偏移量的分页

Offset pagination can be used when you do not care about chronology and just want a specific number of objects returned. 当您不关心年表并且只想要返回特定数量的对象时,可以使用偏移分页。 This should only be used if the edge does not support cursor or time-based pagination. 仅当边缘不支持光标或基于时间的分页时才应使用此选项。

So what you have found with Offset is the closest you will get to the stock-standard pagination you desire. 所以你在Offset中发现的是你最接近你想要的股票标准分页。 However: 然而:

Offset based pagination is not supported for all API calls. 所有API调用都不支持基于偏移的分页。 To get consistent results, we recommend you to paginate using the previous/next links we return in the response. 为了获得一致的结果,我们建议您使用我们在响应中返回的上一个/下一个链接进行分页。

You can read all this in the FB API docs. 您可以在FB API文档中阅读所有这些内容。

https://developers.facebook.com/docs/graph-api/overview/ https://developers.facebook.com/docs/graph-api/overview/
https://developers.facebook.com/docs/graph-api/using-graph-api/ https://developers.facebook.com/docs/graph-api/using-graph-api/

Finally after doing some researches and reading some blogs I found out that there is no direct API CAlls from facebook to fetch all user feeder posts in once. 最后,在做了一些研究和阅读一些博客后,我发现Facebook没有直接的API CAlls来一次获取所有用户馈送帖子。 To achieve that functionality either one has to go for infinite scrolling as suggested by Jeremy Thomson or to iterate through different facebook data pages regardless of which facebook pagination type is supported by the edge . 为了实现该功能,要么必须按照Jeremy Thomson的建议进行无限滚动,要么迭代不同的facebook数据页,而不管edge支持哪种facebook pagination类型。 As far as I want a process without user interference/actions I would definitely go the second option which is iterating through facebook data pages with a while loop. 至于我想要一个没有用户干扰/动作的过程,我肯定会选择使用while循环遍历facebook数据页面的第二个选项。 To do That we first need our two most important parameters (facebook access_token + (facebook appsecret_proof ) as described below: 要做到这一点,我们首先需要两个最重要的参数(facebook access_token +(facebook appsecret_proof ),如下所述:

var appsecret_proof = access_token.GenerateAppSecretProof();
var fb = new FacebookClient(access_token);

Point to be remembered: facebook access_token is generated by HttpContext class. 值得记住的点:facebook access_token是由HttpContext类生成的。

The facebook API call will get the users first 25 feeder post as below: facebook API调用将获得用户前25个馈线帖子,如下所示:

dynamic myFeed = await fb.GetTaskAsync(
                    ("me/feed?fields=id,from {{id, name, picture{{url}} }},story,picture,link,name,description," +
                    "message,type,created_time,likes,comments")
                    .GraphAPICall(appsecret_proof));

The API Call above return results in a Json array and that should be hydrated through the Model View properties as shown here: 上面的API调用返回会生成一个Json数组,并且应该通过Model View属性进行水合,如下所示:

var postList = new List<FacebookPostViewModel>();
    foreach (dynamic post in myFeed.data)
       {
         postList.Add(DynamicExtension.ToStatic<FacebookPostViewModel>(post));
       }

Until here everything was clear before, the most important part which is surely fetching all facebook user post is now in action. 直到这里一切都很清楚,最重要的部分肯定是取得所有Facebook用户的帖子现在正在行动。 For that we need to set a string NextPageUri to empty as here: 为此,我们需要将string NextPageUri设置为空,如下所示:

string NextPageURI = string.Empty;

The final part of all is to check if there is another page for the data, If yes should iterate and add the data to the View Model until there is no page lift as shown here: 最后一部分是检查是否有另一个数据页面,如果是,则应迭代并将数据添加到View Model直到没有页面提升,如下所示:

while (myFeed.paging != null && myFeed.paging.next != null)
                {
                    NextPageURI = myFeed.paging.next;
                    var nextURL = GetNextPageQuery(NextPageURI, access_token);
                    dynamic nextPagedResult = await fb.GetTaskAsync(nextURL.GraphAPICall(appsecret_proof));
                    foreach (dynamic post in nextPagedResult.data)
                    {
                        postList.Add(DynamicExtension.ToStatic<FacebookPostViewModel>(post));
                    }
                }

This helped me to get rid of the problem faced. 这有助于我摆脱面临的问题。 But yet I have another task in hand to work on. 但是我还有另一个任务可以继续。 It is the speed of fetching the posts that if posts are morethan 30k would take 10 minutes which is not ideal at least for me. 这是获取帖子的速度,如果帖子超过30k需要10分钟,这对我来说并不理想。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM