I'm trying to query Facebook for the last 50 photos posted by my friends.
Sounds easy enough, right? So far I've found two different approaches using FQL, and neither works.
Photo Method [Explorer]
SELECT pid, owner, src_big, caption, created
FROM photo WHERE owner IN (
SELECT uid1 FROM friend WHERE uid2=me()
) ORDER BY created DESC LIMIT 50
The problem with this is that it's doing a depth-first search when I really want a breadth first search. It's going through my friends list, finding the first friend with a bunch of photos, and then giving me back her most recent photos, ignoring more recent photos from friends further down on my friends list.
Stream Method [Explorer]
SELECT pid, owner, src_big, caption, created
FROM photo where pid in (
SELECT attachment.media.photo.pid
FROM stream
WHERE filter_key IN (
SELECT filter_key FROM stream_filter WHERE uid=me()
) AND type = 247
ORDER BY created_time DESC
LIMIT 50
)
This is much closer to what I want, except that it's giving me photos from pages, too, and I only want photos from friends. As far as I can tell, there is no way to filter uid by type (e.g. friend, page, etc.).
What am I missing? Is there a third way? Is this impossible?
I tried your query and timeout error encountered(by this time):
Your main key should put filter_key with app_2305272732 in the first place to return photo only, instead of filter by type=247 afterward, so you can get more results:
SELECT pid, owner, src_big, caption, created FROM photo where pid IN(SELECT attachment.media.photo.pid FROM stream WHERE filter_key='app_2305272732' AND actor_id IN(SELECT uid1 FROM friend WHERE uid2=me()) AND created_time<=now() ORDER BY created_time DESC LIMIT 200)
As you can see, the actor_id only include friends, but the response can be faster(~2 seconds for 2000 friends) if you put actor_id directly, so you may consider to cache the friends id (depends on your app flow).
actor_id IN(FRIEND_ID1,FRIEND_ID2,FRIEND_ID3...)
Also, there's no guarantee to get 50 photos in once, but you can navigate to next page by created_time(Get from last photo's created field). Even thought the created time from photo table may slightly different(~1 seconds) than stream table, but it should acceptable.
created_time<CREATED
Finally, you should increase the limit, so you can get more result at once. I found 200 is acceptable and i'm able to get more than 20 photos in one page.
LIMIT 200
Update:
You should use source_id instead of actor_id, to get much more results. So the correct query is:
SELECT pid, owner, src_big, caption, created FROM photo where pid IN(SELECT attachment.media.photo.pid FROM stream WHERE filter_key='app_2305272732' AND source_id IN(SELECT uid1 FROM friend WHERE uid2=me()) AND created_time<=now() ORDER BY created_time DESC LIMIT 200)
The LIMIT parameter can be decrease if you do this query, let's say LIMIT 50, so your single query can be faster and avoid timeout request failed(if the photos data is too many and too heavy), it's depends on your decision.
I have to remind you, you can't simply use created from photo table to query next page of stream table, because a feed may contains many photos and the created time for each photos can be much more different(the distinct can be in hours!). So you should consider to do multiquery to retrieve created_time of stream table if you want to do next page, for example:
{"query1":"SELECT attachment.media.photo.pid, created_time FROM stream WHERE filter_key='app_2305272732' AND source_id IN(SELECT uid1 FROM friend WHERE uid2=me()) AND created_time<=now() ORDER BY created_time DESC LIMIT 200", "query2":"SELECT pid, owner, src_big, caption, created FROM photo where pid IN(SELECT attachment.media.photo.pid FROM #query1)"}
Also, please note that ORDER BY created DESC is sort the feed, not photo, so it's normal if you see the create time is not in the order.
You may consider to do comparison for every single photo's created time with next page's created_time, and only show the photo which are currently earlier than next page's created_time. For example, if the next page created_time is 5.00 PM, and you have the photo A with created time at 2.00 PM(get from first page). You can just hold on the photo A until the next page created_time is older than 2.00 PM, so you can display photo A to the user. Of course, you have to do sorting after you insert photo A to current page's photos.
Related
Using facebook FQL, I got status_id, message and time. But I also want a link to that status. This link should direct me to that status on facebook.com . Is there any easy way to do this? Thanks..
Edit
Code:
SELECT status_id, time, message, comment_info, like_info
FROM status WHERE uid = me()
AND time > 1325356200 AND time < 1356978600
ORDER BY status_id
Can I get url to my first status update?
You can query permalink, for example:
https://developers.facebook.com/tools/explorer/?fql=SELECT%20post_id%2Cmessage%2Cpermalink%20FROM%20stream%20WHERE%20source_id%3Dme()
Documentation: https://developers.facebook.com/docs/reference/fql/stream/
SELECT status_id, time, message, comment_info, like_info
FROM status WHERE uid = me()
AND time > 1325356200 AND time < 1356978600
ORDER BY status_id
Using status_id,
you can get facebook link using, https://www.facebook.com/{{ username }}/posts/{{ status_id }}
How can i get a list of facebooks top 10,000 facebook fan pages - ranked by number of likes?
I found this site that lists the top 100: http://fanpagelist.com/
and this company that analysed the top 600,000: http://www.sysomos.com/insidefacebook/
is there a way to get this data programmatically?
I think this is basically impossible because you can't search for all pages, you must have some criteria when searching that matches with an indexable column. You can see those indexed columns with a * (Star) next to them on this page:
https://developers.facebook.com/docs/reference/fql/page
As you can see, the 'fan_count' property is listed for a page, but you can't search for every page then rank my the 'fan_count' property.
what you can do, is search within all of your friends fan pages, and return the highest x after sorting.
You can use this query:
Select name, fan_count FROM page WHERE page_id IN (SELECT page_id FROM page_fan WHERE uid IN (SELECT uid2 FROM friend WHERE uid1== me()) limit 10) ORDER BY fan_count DESC
On this page: link (Click on FQL query)
On this page you can see the top liked pages from a selection of 10 of your friends. If you remove the 'limit 10' from the query you will see the query fail because its too big. You could however list your friends in order, and then cycle through them 10 at a time and collecting all of the results.
You can try this using the Graph API Explorer:
SELECT post_id, id, fromid, time, text, user_likes, likes FROM comment WHERE post_id ='126757470715601_530905090300835' AND time < '1366318653' ORDER BY time DESC LIMIT 30
This will return an empty result set. BUT if I remove DESC from the query, it will return 30 results.
SELECT post_id, id, fromid, time, text, user_likes, likes FROM comment WHERE post_id ='126757470715601_530905090300835' AND time < '1366318653' ORDER BY time LIMIT 30
So adding DESC to the order by somehow changed the way LIMIT behaves. Can anyone shed some light on this?
Update:
The time is within range. Sorry by my wrong calculation before. What you can do is increase the comment number to huge value, such as LIMIT 150, because there's may be a lot of comments is_privacy='0' around 30 items.
I am trying to retrieve the object_id of all pictures that my friends has on facebook.
This is the method I use that I believe should work fine:
https://api.facebook.com/method/fql.query?access_token=[YOURTOKEN]&query=SELECT object_id FROM photo WHERE aid IN (SELECT aid FROM album WHERE owner IN (SELECT uid FROM friend WHERE uid1=me )) ORDER BY created DESC
My problem is that I only retrieve 5108 object_id's , thats nowhere close to the total number of pictures that all of my friend has.
Is there a restriction from facebook ? Any suggestions appreciated.
You can add LIMIT and OFFSET to the end of your query. So to get the first 1000 photos, you would have LIMIT 1000 OFFSET 0, then for the next group LIMIT 1000 OFFSET 1001 and so on.
You are also using a legacy endpoint. You should be using the newer one:
https://graph.facebook.com/fql?q=[QUERY]&access_token=[TOKEN]
When I run the following FQL query in two Graph API explorer windows at the same time, I get two different result sets:
SELECT
post_id,
actor_id,
target_id,
created_time,
type,
permalink,
message,
description,
attachment
FROM stream
WHERE filter_key IN (SELECT filter_key
FROM stream_filter
WHERE uid=me() AND type='newsfeed')
ORDER BY created_time ASC
LIMIT 50
Here are the differences:
The 1st result set has a few extra posts in the start, whereas the 2nd has a few extra posts in the end (I use ORDER BY created_time ASC in the FQL.)
One of the posts in between has an empty permalink in the 1st result set, whereas its present in the 2nd result set.
There are few posts not present in the 1st result set which are present in 2nd, and vice versa.
Is this because of load balancing within the Facebook server farm?
How can one make sure they are getting all posts which can be seen on the user's newsfeed via the API?