Can´t get age_range from Facebook API - json

According to Facebook documentation, age_range is a default property when requesting user data:
https://developers.facebook.com/docs/facebook-login/permissions#reference-basic-info
This does work when I use "me" as the user-id with the proper token:
https://graph.facebook.com/me?fields=id%2Cname%2Cemail%2Cfirst_name%2Clast_name%2Cusername%2Cgender%2Cpicture%2Cage_range&format=json&access_token=[accessToken for required user]
{
"id": "FACEBOOKID",
"name": "testuser",
"email": "testuser\u0040test.net",
"first_name": "testuser",
"last_name": "testuser",
"gender": "male",
"age_range": {
"min": 21
},
"picture": {
"data": {
"url": "https://...",
"is_silhouette": false
}
}
}
But the data_range is then empty when I use the user id:
https://graph.facebook.com/[FacebookId]?fields=id%2Cname%2Cemail%2Cfirst_name%2Clast_name%2Cusername%2Cgender%2Cpicture%2Cage_range&format=json&access_token=[AccessToken]*
Gives me back:
{
"id": "FACEBOOKID",
"name": "testuser",
"email": "testuser\u0040test.net",
"first_name": "tftestuser",
"last_name": "tftestuser",
"gender": "male",
"picture": {
"data": {
"url": "http://....",
"is_silhouette": true
}
}
}
Any idea why? What am I missing here?
Thank you in advance!

I found an answer using the API here:
no age_range in facebook response (javascript sdk)
The api call "/me" returns the default info, which doesn't always include age_range.
However you can request age_range with the api call:
"/me?fields=age_range"

According to Platform Updates: Operation Developer Love -
accessible for all users that install your app
So age_range won't be returned if the user hasn't installed your app. As in your case, that user might not be using the app for which you are getting this blank.
Also the purpose of age_range field is to let your app determine whether your app can provide some age-sensitive contents. So, retrieving age_range for user's friends is inappropriate and you'll have to get friends_birthday permission.
EDIT:
The link also says-
mobile apps and websites that use Facebook Login to restrict their content to people age 18+ and 21+
That means this field is available only for the apps who have restricted their content to people age 18+ and 21+- please check!

I too spent hours on trying to find a solution for this.
Am sharing my experience below:
I initially asks for an fb session by asking for user details with the following permissions:
session.openForRead(new com.facebook.Session.OpenRequest(
LoginActivity2.this).setPermissions(
Arrays.asList("public_profile","email")).setCallback(
statusCallback));
With a valid session I then call a request using this code block:
new Request(
session,
graphPath,
bundle,
HttpMethod.GET,
new Request.Callback() {
#Override
public void onCompleted(Response response) {
Log.v(TAG, "response = xx" +
response.toString());
String age_min = "";
String age_max = "";
GraphObject graphObject = response.getGraphObject();
Map<String, Object> stateMap = graphObject.asMap();
try {
JSONObject age_range = (JSONObject) stateMap.get("age_range");
age_min = age_range.getString("min");
age_max = age_range.getString("max");
} catch (Exception e) {
Log.v(TAG, "error in parsing age_range here = " + e.getMessage());
}
Log.v(TAG, "logging the age_range min here = " + age_min);
Log.v(TAG, "logging the age_range max here = " + age_max);
if (!"".equalsIgnoreCase(age_max)) {
if ("18".equalsIgnoreCase(age_max)) {
age_range = "0-18";
} else if ("21".equalsIgnoreCase(age_max)) {
age_range = "18-21";
}
} else if (!"".equalsIgnoreCase(age_min)) {
if ("18".equalsIgnoreCase(age_min)) {
age_range = "18-21";
} else if ("21".equalsIgnoreCase(age_min)) {
age_range = "21-100";
}
}
Log.v(TAG, "and here in FB2 the age_range is = " + age_range);
}
}
).executeAndWait();
Where:
session (string) --> valid and currently opened session
graphPath (string) --> this is the fb userID (can be "me" but I haven't tested that, please let me know if "me" works.
bundle --> is the K,V parameter that you will request, in the age_range case it is:
Bundle bundle = new Bundle();
bundle.putString("fields", "age_range");
Please note that the request code block (at least in my case) was done inside the doinBackground of inner AsyncTask) --> thus my use of the executeAndWait() method instead of the executeAsync().
Hope this will help someone with the same problem. Thanks!

You can retrieve only currently logged-in user's OWN age_range and can not query other's age therefore you get no response when provided user_id is not the same as own id
see https://stackoverflow.com/a/30731037/4990217
You'll have to explicitly tell the API that you need age_range, as part of the public profile (no special permissions required). The user's age range may be 13-17, 18-20 or 21+.
/* make the API call v.2.3 */
FB.api(
"/me?fields=age_range",
function (response) {
if (response && !response.error) {
/* handle the result */
}
}
);
read documentation https://developers.facebook.com/docs/graph-api/reference/age-range/

Related

How to pass multiple records in REST API POST method using JSON body

I have a requirement where I need to create multiple records in my custom object using REST API POST method.
Now the problem is I am able to create one record at a time and I am not able to create multiple records in one REST API call. I have found on net by passing JSON request body i will be able to create multiple records.
I am completely new to integration and don't understand how to create mutilple records in one REST API call and how can i pass JSON request body in my REST API.
Can somebody help me in achiving my requirement please.
Here I am posting my code for reference:
#HttpPost
global static ID createAddress(String Address, String City, String FirstName, String LastName, String Phone, String Email
) {
//First find the contact id matching the email.
String ContactId = [SELECT Id
FROM Contact
WHERE Email = :Email].Id;
//Second post the new ListofAddresses to the owner of the email.
Address__c thisAddress = new Address__c(
Contact__c=ContactId,
Address__c=Address,
City__c=City,
First_Name__c=FirstName,
Last_Name__c=LastName,
Phone__c=Phone,
);
/* List<Address__c> result = [SELECT Address__c, City__c, First_Name__c, Last_Name__c, Phone__c
FROM Address__c
WHERE Contact__c = :ContactId];
if(result.size() > 0){
return null;
}else{*/
insert thisAddress;
return thisAddress.Id;
}
Try this code for passing multiple record using the Json format
#RestResource(urlMapping='/Account/*')
global class MyRestResource {
#HttpPost
webService static String doPost() {
Account account = new Account();
RestRequest req = RestContext.request;
List<jsonWrap> jsonWrapList = (List<jsonWrap>)JSON.deserialize(req.requestbody.tostring(),List<jsonWrap>.class);
return 'Account Success';
}
public class jsonWrap{
String Namex;
String phonex;
String websitex;
}
}
Sample Json
[
{
"Namex": "test1",
"phonex": "12312",
"websitex": "test.com"
},
{
"Namex": "test2",
"phonex": "12312",
"websitex": "test.com"
},
{
"Namex": "test2",
"phonex": "12312",
"websitex": "test.com"
}
]

Error 400/401 trying to create a webhook

I am brand new to webhooks and have had a nightmare trying to get my first one to function. I am trying to use a Particle Photon to send a single float temperature variable to a site that can graph the data. I've tried creating webhooks to thingspeak.com and librato.com with no success. My main attempts have been trying to use the json code in tutorials to create the webhook.
Here is my Photon's code:
#include "Particle.h"
float temp = 70.1000;
float adjust = 0.4;
int acOn = 0;
void setup()
{
}
void loop()
{
if(temp < 72)
adjust = random(1620000)/1000000.0;
else if(temp < 74)
adjust = random(1000000)/1000000.0;
else
adjust = -1*random(500000,2200000)/1000000.0;
temp = temp + adjust;
Particle.publish("librato_", String(temp), 60, PRIVATE);
Particle.process();
delay(30000);
}
and the webhook JSON code (for the librato attempt)
{
"event": "librato_",
"url": "https://metrics-api.librato.com/v1/metrics",
"requestType": "POST",
"auth": {
"username": "YOUR_LIBRATO_USERNAME",
"password": "YOUR_LIBRATO_API_TOKEN"
},
"json": {
"gauges": [
{
"name": "{{NAME}}",
"value": "{{temp}}",
"source": "{{PARTICLE_DEVICE_ID (particle API token?)}}"
}
]
},
"mydevices": true
}
where I have filled in the username and API token found on librato and also the particle api token in the IDE settings. Thanks in advance for the help.
Looks like this user had a similar problem which was solved with a simple renaming or the webhook:
https://community.particle.io/t/connection-to-librato-solved/19230
Check with the Particle CLI if any events are being generated. If you are still not seeing data in Librato, reach out to support#librato.com so that we can check the API for errors.

Zuora Authentication Issue #code 90000011

When I call 'https://apisandbox-api.zuora.com/rest/v1/accounts' with required apiAccessKeyId, apiSecretAccessKey and parameters, I recieve the response
{
"success": false,
"reasons": [
{
"code": 90000011,
"message": "this resource is protected, please sign in first"
}
]
}
Not clear what is exact issue.
You need to call the connection api first in order to access any object in the Zuora sandbox.
Request URL
GET: https://apisandbox-api.zuora.com/rest/v1/connections
and the response you would see:
{
"success": true
}
Give it a try after calling this Api. It should be resolved then.Thanks.
You need to sign in first, there is an example in the Zuora SDK using a ConnectionManager source :
final ZClient Z_CLIENT = new ZClient();
final ConnectionManager cm = new ConnectionManager();
if (!cm.isConnected(Z_CLIENT, (String) ZConfig.getInstance().getVal("default.tenant.user.id"),
(String) ZConfig.getInstance().getVal("default.tenant.password")))
{
throw new RuntimeException("Couln't open a connection to Zuora API !");
}

Edit video metadata using clickntap api error

I'm trying to edit the metadata for the video which i have uploaded and I have been getting error status 400 in the response from the vimeo server. I'm using ClicknTap api for java.
The parameters are all correct as from my perspective and code is attached below.
Vimeo vimeo = new Vimeo("c8a84c2f936c934a4735bc22bdcd5fa0");
String name = "Demo1";
String desc = "Description here";
String license = "";
String privacyView = "disable"; // see Vimeo API Documentation
String privacyEmbed = "whitelist";
boolean reviewLink = false;
VimeoResponse respon=vimeo.updateVideoMetadata(videoEndPoint,name,desc,license,privacyView, privacyEmbed, reviewLink);
System.out.println(respon);
The output is as shown below:
HTTP Status Code:
400
Json:
{
"developer_message": "The parameters passed to this API endpoint did not pass Vimeo's validation. Please check the invalid_parameters list for more information",
"link": null,
"error_code": 2204,
"error": "You have provided an invalid parameter. Please contact developer of this application.",
"invalid_parameters": [{
"field": "privacy.view",
"developer_message": "The parameters passed to this API endpoint did not pass Vimeo's validation. Please check the invalid_parameters list for more information",
"error_code": 2204,
"error": "You have provided an invalid parameter. Please contact developer of this application."
}]
}
I found out my mistake. I changed privacyView and privacyEmbed values to nobody and private respectively and the code worked. The clean code is as follows.
String name = "Demo1";
String desc = "Description here";
String license = null;
String privacyView = "nobody";
String privacyEmbed = "private";
boolean reviewLink = false;
VimeoResponse respon = vimeo.updateVideoMetadata(videoEndPoint,
name, desc, license, privacyView, privacyEmbed, reviewLink);
Hope this would be helpful for someone in future.

Facebook Graph API not returning standard JSON

I am working on an iOS app using the MonoTouch framework. I am using Visual Studio 2010 Professional SP1 with the Xamarin.iOS (v1.3.250) extension. I have been able to open a valid FacebookConnect.FBSession by using the FacebookConnect.FBLoginView with no issues but when I try to make a Graph API request using FacebookConnect.FBRequest I recieve a non-standard JSON style string. When I run following request through the Graph API Explorer:
me?fields=albums.fields(id,name,cover_photo)
I receive the following response:
{
"id": "111111111111111111",
"albums": {
"data": [
{
"id": "111111111111111111",
"name": "Some Album (#1)",
"cover_photo": "111111111111111111",
"created_time": "000-00-00T00:00:00+0000"
},
{
"id": "111111111111111111",
"name": "Some Album (#2)",
"cover_photo": "111111111111111111",
"created_time": "000-00-00T00:00:00+0000"
},
],
"paging": {
"cursors": {
"after": "xxxxxxxx=",
"before": "xxxxxxxx="
}
}
}
}
Now all of this is just fine and is what I expect to receive but when I make the same Graph API request from my app like this:
public static void GetPhotoAlbums(string _userID)
{
// _userID = "me"
mFBRequest = new FBRequest(FBSession.ActiveSession, _userID + "?fields=albums.fields(id,name,cover_photo)");
FBRequestConnection fbRequestConnection = new FBRequestConnection();
fbRequestConnection.AddRequest(mFBRequest, OnPhotoAlbumsReceived);
fbRequestConnection.Start();
}
static void OnPhotoAlbumsReceived(FBRequestConnection _connection, NSObject _result, NSError _error)
{
if (_error == null)
{
Console.WriteLine("FacebookManager.OnPhotoAlbumsReceived() - JSON: " + _result.Description);
object o = JsonConvert.DeserializeObject(_result.Description);
// ...
}
}
I receive this JSON 'like' response:
{
albums = {
data = (
{
"cover_photo" = 111111111111111111;
"created_time" = "000-00-00T00:00:00+0000";
id = 111111111111111111;
name = "Some Album (#1)";
},
{
"cover_photo" = 111111111111111111;
"created_time" = "000-00-00T00:00:00+0000";
id = 111111111111111111;
name = "Some Album (#2)";
},
);
paging = {
cursors = {
after = "xxxxxxxx=";
before = "xxxxxxxx=";
};
};
};
"id": "111111111111111111";
}
I'm not really sure how/why I'm getting a response formatted in a non-standard way but needless to say, I get Newtonsoft.Json.JsonReaderException when attempting to deserialize the data because it does not follow the standard formatting rules (ie, = instead of : to separate key/value pairs, ; instead of , to separate elements of a container, some keys having quotes while others do not, etc...)
I'm pretty new to Facebook and JSON stuff in general and am really at a loss for what is happening to the response string I receive. Any help, feedback, ideas are greatly appreciated. Thanks.
* Solution *
After a bunch of digging around it seems to be that the Graph API response is indeed JSON but it gets converted to an FBGraphObject which holds a NSMutableArray as it the data makes its way through the MonoTouch->.NET bindings so when I pulled _result.Description (equivalent to _result.ToString() it returned me the string representation of that object which happens to look a lot like JSON but is not. After finding all this out (and a lot of runtime experimentation), I was finally able to extract the data into a usable state by doing this:
static void OnPhotoAlbumsReceived(FBRequestConnection _connection, NSObject _result, NSError _error)
{
if (_error == null)
{
NSArray fieldData = (NSArray) _result.ValueForKeyPath(new NSString("albums.data.name"))
string[] names = NSArray.StringArrayFromHandle(fieldData.Handle);
// ...
}
}
Although this works for me, I have a feeling that there is a better or more robust way to get the data I requested, so if any developers out there can offer any additional tips for improving this solution, I would love to hear them.
As stated in Facebook SDK documentation Graph API:
When a request returns a non-JSON response (such as a "true" literal),
that response will be wrapped into a dictionary using this const as
the key. This only applies for very few Graph API prior to v2.1.
So you can check first if result is an NSDictionary, otherwise you can deserialize the JSON data as usual.
Below some obj-c code you can translate into C#/MonoTouch (I don't know the framework, I hope it is helpful).
NSDictionary *dict;
if ([graphResult isKindOfClass:[NSDictionary class]]) {
dict = (NSDictionary *)graphResult;
} else {
NSError *JSONError;
dict = [NSJSONSerialization JSONObjectWithData:graphResult options:NSJSONReadingAllowFragments error:&JSONError];
if (JSONError) {
NSLog(#"Facebook: JSON parse error: %#", JSONError);
// Handle error
}
}