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]
Related
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.
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.
I'm having some trouble to retrieve a sequence of posts using FQL when sorting by *created_time*. It seems that when I try to retrieve posts ordering by *created_time*, FQL first retrieves the first 50 posts (LIMIT 50) ordered by *updated_time* and then apply ORDER BY on these first 50 posts.
The *updated_time* datetime gets updated whenever someone comments on that post, so if someone comments on a post that's 1 year old, the last post from my first query will be that post and my next sequence will start from that point in time (older than 1 year).
This causes me a problem because to get the next 50 posts in the sequence, I have to use the *created_time* datetime from the last post from the first query.
Any ideas on how to this the correct way?
SELECT post_id,actor_id,message,created_time,updated_time FROM stream WHERE source_id=xxx AND created_time < xxxxxxxx ORDER BY created_time DESC LIMIT 50
Example:
There is a post with timestamps: 'updated_time': 1372837741 and 'created_time': 1372081023
With the following query, there are no results although the post's created_time is inside the specified created_time range.
SELECT post_id,actor_id,message,permalink,created_time,updated_time FROM stream WHERE source_id=xxxxxxxxx
AND created_time < 1372081033
AND created_time > 1372081013
But if I change the query's range to include the post's updated_time, the post above is returned.
SELECT post_id,actor_id,message,permalink,created_time,updated_time FROM stream WHERE source_id=xxxxxxxxxxx
AND created_time < 1372837742 AND created_time > 1372081013
This is probably a bug.
Thanks in advance!
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 need to monitor number of the facebook group users and display it on the website. I know that it is possible to get User IDs using their API, but they are limited to 500 only (if the total number of members is 500+).
What would be the easiest way to get total number of members that signed up to a Facebook Group that I'd set up? Is this at all possible?
If you write an http bot, it shouldn't be very hard to scrap, given that real-time performance is not the key.
You can do it with a FQL query like this:
SELECT uid FROM group_member WHERE gid = <group_id> limit 500
SELECT uid FROM group_member WHERE gid = <group_id> limit 500 offset 500
SELECT uid FROM group_member WHERE gid = <group_id> limit 500 offset 1000
...
Get the number of members
Do it inside a loop (until you get 0 results) and you'll get the total number of group members
perPage = 500
for count in range(100):
res = fql('SELECT uid FROM group_member WHERE gid = %s limit %d offset %d' % (fbUserId, perPage, perPage * count))
if len(res) == 0:
break
friends += len(res)
Get the members detail
You can even join with the user FQL table to have all the user detail:
SELECT uid, name, pic_square FROM user WHERE uid IN (
SELECT uid FROM group_member WHERE gid = <group_id> limit 500 offset %d )
According to the documentation for Groups.getMembers it isn't possible to get > 500 group members with an API call. Worse, you seem to only be able to get 500 random members.
You may want to consider using Facebook Connect with your site instead. I'm no expert on Connect but I believe you wont have this problem using it since you are actually writing Facebook-specific code -- seems like there would be no purpose in limiting results. That'd be the direction I'd look, at least.
Good luck.