20

I'm developing a Facebook application using their Graph API. I have previously developed an app using the deprecated REST API.

I've come across a problem in that I can't retrieve the user's country, only their 'location' - which is just the city and state / region in a combined format (such as 'Houston, Texas').

How is it possible to retrieve the user's country using the Graph API? If this isn't directly possible, what workarounds might there be to achieve this?

BrynJ
  • 8,322
  • 14
  • 65
  • 89

10 Answers10

23

https://api.facebook.com/method/fql.query?format=json&query=SELECT%20current_location%20FROM%20user%20WHERE%20uid=4&access_token=<ACCESS_TOKEN>

[
  {
    "current_location": {
      "city": "Palo Alto",
      "state": "California",
      "country": "United States",
      "zip": "",
      "latitude": 37.4441,
      "longitude": -122.163,
      "id": 104022926303756,
      "name": "Palo Alto, California"
    }
  }
]

FQL Documentation

evandrix
  • 6,041
  • 4
  • 27
  • 38
Valerchik
  • 254
  • 1
  • 3
  • 1
    Just a small contribution: here is an official post on how to use the Graph API for issuing FQL queries (and it also says that FQL will not be deprecated; a common misconception): https://developers.facebook.com/blog/post/579/ – YOMorales Feb 29 '12 at 22:48
  • Facebook returns current_location as '' for other than my id, though location details are public of the users i had tested, including MZ's id, which is 4. Please help. Thanks! – lupchiazoem Jun 29 '13 at 02:51
6

One solution I have found, which is merely a workaround, is to use the GeoNames API - http://www.geonames.org/export/web-services.html

Using something like:

http://api.geonames.org/search?q=houston%2C%20texas&featureClass=P&username=myusername

Returns results in an xml object, with the country as part of the data.

I'm not particularly happy with this as a solution however, as it adds an unnecessary layer of complications on to my application - plus requests to this free services are limited to 2000 per hour and 30,000 per day.

BrynJ
  • 8,322
  • 14
  • 65
  • 89
  • I've added a correction to my answer - it is 2000 requests per hour, or 30,000 a day - and also added a parameter that limits matches to cities / towns / villages. – BrynJ Feb 28 '11 at 20:21
6

Use the php sdk:

require 'facebook.php';

$facebook = new Facebook(array( 'appId' => 'APPID', 'secret' => 'APPSECRET',
'cookie' => true, ));

Then ask for a signed request:

  $signed_request = $facebook->getSignedRequest();
  $country = $signed_request["user"]["country"];

Now $country has a string such as "us" for United States and "uk" for United Kingdom etc.

Tom
  • 9,275
  • 25
  • 89
  • 147
1

You should try like this:

/* make the API call */
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection,
                                                           NSDictionary<FBGraphUser> *user,
                                                           NSError *error)
    {
        if (!error)
        {
            self.countryName    = [[[user objectForKey:@"location"] valueForKey:@"name"] componentsSeparatedByString:@", "][1];
            self.countryCode    = [self getCountryCodeForCountry:STUser.countryName];
        }
}];

-(NSString *)getCountryCodeForCountry:(NSString*)country
{
    NSMutableArray *countries = [self getCountries];
    NSArray *countryCodes = [NSLocale ISOCountryCodes];

    NSDictionary *codeForCountryDictionary = [[NSDictionary alloc] initWithObjects:countryCodes forKeys:countries];

    return [codeForCountryDictionary objectForKey:country];
}

+(NSMutableArray *)getCountries
{
    NSMutableArray *countries = [NSMutableArray array];

    NSArray *countryCodes = [NSLocale ISOCountryCodes];
    countries = [NSMutableArray arrayWithCapacity:[countryCodes count]];

    for (NSString *countryCode in countryCodes)
    {
        NSString *identifier = [NSLocale localeIdentifierFromComponents:[NSDictionary dictionaryWithObject: countryCode forKey: NSLocaleCountryCode]];
        NSString *country = [[NSLocale currentLocale] displayNameForKey: NSLocaleIdentifier value: identifier];
        [countries addObject: country];
    }

    return countries;
}
NeverHopeless
  • 11,077
  • 4
  • 35
  • 56
1

use the official Facebook Graph API /me?fields=hometown it will return you e.g. "Prague, Czech Republic"

I believe you can explode the string by needle ',' and the last element should be the country

evandrix
  • 6,041
  • 4
  • 27
  • 38
Jakub Folejtar
  • 320
  • 1
  • 2
  • 11
1

That is a good question.

The problem is that any application run under facebook has to go through facebook servers - fb proxy and because of this the IP you get is not that of visitors but facebook's servers' instead which is of no use.

I have not seen any solution for this yet except for getting user's country from his profile which again is only possible if user had made it public or authorized the permission for it.

Here is useful link you might want to check out there too:

Sarfraz
  • 377,238
  • 77
  • 533
  • 578
  • Thanks for the info Sarfraz. I find it incredible frustrating that Facebook have not made the equivalent information available in the Graph API - they are effectively encouraging users to continue using the retired REST API. It's especially frustrating as country is such a fundamental and harmless piece of information. Do you have a link to any info on accessing the country directly via a user's public profile? – BrynJ Feb 28 '11 at 15:24
  • @BrynJ: I could find these links: http://stackoverflow.com/questions/2723038/facebook-graph-api-user-gender and http://stackoverflow.com/questions/4609781/facebook-api-can-i-get-detailed-info-about-users-location – Sarfraz Feb 28 '11 at 15:32
0

According to Facebook's documentation, you can get the 2-letter ISO 3166-1 country code from the user's locale.

Facebook locales follow ISO language and country codes respectively, concatenated by an underscore. The basic format is ''ll_CC'', where ''ll'' is a two-letter language code, and ''CC'' is a two-letter country code. For instance, 'en_US' represents US English.

Example FQL:

SELECT locale FROM user WHERE uid = me()

Response:

{
  "data": [
    {
      "locale": "en_US"
    }
  ]
}
Mike Valenty
  • 8,941
  • 2
  • 30
  • 32
  • 4
    This information may be different from the location information they have associated with their profile and are two different profile settings. – Keith May 10 '13 at 18:29
  • 3
    Agree to @Keith. I live in Germany, still my locale is en_US - just because I picked it! – BlaM Jul 26 '13 at 15:51
  • And a lot of South America countries have the same locale es_LA – Robertiano Jun 13 '14 at 09:38
  • locale actually represents the language you're using on Facebook. If I change to US English, my locale becomes "en_US", if I change to Brazil Portuguese it becomes "pt_BR" – Danilo Lima Sep 04 '14 at 19:06
0

You can see the lifetime number of followers (by likes to your FB page) by country using an FQL query. Set up a JSON query using the tokenized session value, and send an FQL query through via PHP with the object_ID of the page you are targeting and period of lifetime. select metric, and set the metric to page_fans_country - and dump the data into a CSV file. You should get back a list of total lifetime followers (by likes) by country code (multiple rows). Setup a pivot table to get an aggregated index across multiple pages of data, and rank by country code. Here's example of the FQL query:

SELECT metric, value FROM insights WHERE object_id=[your page ID goes here] AND metric='page_fans_country' AND end_time=end_time_date('2013-04-28') AND period=period('lifetime')

0

Answer posted by Valerchik is the right one indeed, but in case someone would look for PHP solution, then I ended up with something like this:

$token = Yii::app()->facebook->getAccessToken();
$fqlRequest = 'https://api.facebook.com/method/fql.query?query=' .
              'SELECT%20' . $fqlAttributeName . '%20FROM%20user%20WHERE%20' .
                    'uid=' . $fbUserId . '&access_token=' . $token;
$ret = file_get_contents($fqlRequest);

if (!empty($ret)) {
    ...

List of all user's attributes can be found here:
https://developers.facebook.com/docs/reference/fql/user/

I hope it will help someone :)

Community
  • 1
  • 1
LihO
  • 41,190
  • 11
  • 99
  • 167
0

for iframe apps, then ip is not hidden by FB servers, meaning you can do ip address lookup

http://phpweby.com/software/ip2country

the script was a bit buggy for me but did the job.

Michael L Watson
  • 964
  • 13
  • 23