Why does FQL always request me to reduce the amount of data I ask for? - facebook-fql

No matter which query I try:
https://developers.facebook.com/tools/explorer/145634995501895/?fql=SELECT%20object_id%2C%20src_small%2C%20src_big%2C%20caption%2C%20modified%20FROM%20photo%20WHERE%20album_object_id%3D154766101216210%20AND%20modified%3E1449682235%20AND%20owner%3D154763454549808%20ORDER%20BY%20modified%20DESC
https://developers.facebook.com/tools/explorer/145634995501895/?fql=SELECT%20object_id%20FROM%20photo%20WHERE%20album_object_id%3D154766101216210%20AND%20modified%3E1449682235%20AND%20owner%3D154763454549808%20ORDER%20BY%20modified%20DESC
https://developers.facebook.com/tools/explorer/145634995501895/?fql=SELECT%20object_id%2C%20src_small%2C%20src_big%2C%20caption%2C%20modified%20FROM%20photo%20WHERE%20album_object_id%3D154766101216210%20AND%20modified%3E1449682235%20AND%20owner%3D154763454549808%20ORDER%20BY%20modified%20DESC%20LIMIT%201
It always ends up saying:
{
"error": {
"code": 1,
"message": "Please reduce the amount of data you're asking for, then retry your request"
}
}
What's the idea? why does nothing works?
P.S. it works sometimes, but you can try the same query one second later, and it won't work anymore.
I would like to somehow get the first query to work.

Related

Return 403 or 201 if a field is not writable

What is the best practice for a response if the user tries to write to a field he or she is not allowed?
Imagine the user wants to create a resource, for example a pizza: POST /pizza
The body:
{
"name": "Hawaii",
"base": "tomato sauce",
"firstMain": "ham",
"secondMain": "pineapple",
"cheese": true
}
Problem is, you can't put secondMain on a pizza (because its pineapple). What's better? Return a 403 error with the message that field secondMain is not writable or return a 201 with the created pizza but without the secondMain?
What's the best practice for this problem? Didn't found anything on Google.
Returning a 403 with a proper error response would work best. Saying 201 but creating something different then what they originally wanted would probably lead to a unhappy customer. I know I'd be annoyed if my pizza didn't come with pineapple and that's what I ordered.
Really guess it varies on a case by case basis depending on your expected result and what your client is expecting to happen. Just make sure to specify in your documentation that extra data sent up with requests that isn't writable will throw an error.
etc
403 response: {error: {"secondMain": "unknown field", "exampleField": "expected but missing"}}

How to get "daily" video views Facebook API?

I have a little experience dealing with Facebook Graph API. I need to get daily views for the video as oppose to lifetime views.
FB API docs don't show this to be an option (lifetime - only period param)
https://developers.facebook.com/docs/graph-api/reference/video/video_insights/
However, I've seen another post on SO answering this question, yet for some reasons it doesn't work for me
(Getting a video views with Facebook API).
This is my successful API call which returns lifetime stats as expected:
/{video_id}/video_insights/total_video_views/lifetime
This is what I thought I should be doing:
/{video_id}/video_insights/total_video_views/day
... but got this error:
{
"error": {
"message": "(#100) Invalid parameter",
"type": "OAuthException",
"code": 100,
"error_data": "Daily query is not supported for metric (total_video_views)"
}
}
Then, as the SO post suggested, I tried different period param:
/{video_id}/video_insights/total_video_views/month
... and got this:
{
"error": {
"message": "(#100) Invalid parameter",
"type": "OAuthException",
"code": 100,
"error_data": "Period should be either lifetime or day."
}
}
... which tells that day should be acceptable param just like lifetime
Eventually, just for fun, I thought I'll pass "wrong" param - Day:
/{video_id}/video_insights/total_video_views/Day
... and got this:
{
"error": {
"message": "(#100) For field 'video_insights': period must be one of the following values: day, week, days_28, month, lifetime",
"type": "OAuthException",
"code": 100
}
}
This states that all of these values are good (day, week, days_28, month, lifetime), yet they don't work.
I'm really confused here. I saw daily break down for a video views on FB webpage/insights and thought it should be possible to do the same through the API.
What am i doing wrong?
I encountered the same problem shortly after your post. All of my testing and research has led me to believe Facebook has removed the ability to retrieve anything other than lifetime. After reading all of the Change Log for the last few releases, I don't see any evidence of this change being documented by Facebook. This is obviously very disappointing.
The API responses clearly indicate "day" should be a valid period, which leads me to believe it was hastily removed.
Unfortunately I do not see a reliable workaround. One may be able to achieve an approximation of daily by retrieving lifetime every 24 hours and calculating the difference between the two. This would only be an approximation though since there could be data reconciliation issues for a given time period.
It is too bad this issue didn't get any traction because it is core to the Facebook Video Insights API.
Here is my solution (after running this through FB support)
basically,
1) i get list of all posts:
fields='object_id,type'
url="https://graph.facebook.com/v3.2/{}?access_token={}&fields={}&limit={}".format(resource_id,access_token,fields,limit)
while url:
rec=requests.request(method="GET",url=url)
content = json.loads(rec.content)
if "next" in content["paging"]:
url=content["paging"]["next"]
else:
url=False
break
2) then, i iterate through each of them (filtering those with videos) and retrieve data for the post which contains this video rather than video itself (which turned out to be not possible anymore with daily grouping)
insights=[]
video_post_id=page_id+"_"+video_id
metric="post_video_views"
url_insight=f"https://graph.facebook.com/v3.2/{video_post_id}/insights?metric={metric}&since={since}&until={until}&pretty=0&access_token={access_token}"
while url_insight:
rec=requests.request(method="GET",url=url_insight)
insight = json.loads(rec.content)
if "next" in insight["paging"]:
url_insight=insight["paging"]["next"]
else:
url_insight=False
break
this worked for me

Google Fit REST API "Unable to fetch DataSource for Dataset: xyz"

I'm testing out a few things in the OAuth 2.0 Playground and trying to get data in and out of Google Fit using their REST API
I have done this previously with success, I just didn't write down what I did.. now I've come back to make it a proper thing and can't get it working again.
I have access to Google Fit datasources via the dashboard. I can get a list of the dataSources that exist from:
https://www.googleapis.com/fitness/v1/users/me/dataSources
And that is successful. I have also created my own stream which has a single floating point weight value on it called
raw:com.google.weight:b6ac18c0:dten.sync
It already has data in it, I put it there last time I used it. I can select all that data by requesting a GET on the following
https://www.googleapis.com/fitness/v1/users/me/dataSources/raw:com.google.weight:b6ac18c0:dten.sync/datasets/0-1432193482000000000
It returns me all the data points I entered last time as JSON
I then try to PATCH the data adding my own data to the folliwng URL
https://www.googleapis.com/fitness/v1/users/me/dataSources/raw:com.google.weight:b6ac18c0:dten.sync/datasets/1432193482000000000-1432193482000000000
With this as a the request body
{
"minStartTimeNs": "1421912895000000000",
"maxEndTimeNs": "1432193482000000000",
"dataSourceId": "raw:com.google.weight:b6ac18c0:dten.sync",
"point": [
{
"startTimeNanos": "1421912895000000000",
"modifiedTimeMillis": "1421912895000",
"endTimeNanos": "1421912895000000000",
"value": [
{
"fPVal": 89.1
}
],
"dataTypeName": "com.google.weight"
}
]
}
But I get back
{
"error": {
"code": 400,
"message": "Unable to fetch DataSource for Dataset: raw:com.google.weight:b6ac18c0:dten.sync",
"errors": [
{
"domain": "global",
"message": "Unable to fetch DataSource for Dataset: raw:com.google.weight:b6ac18c0:dten.sync",
"reason": "invalidArgument"
}
]
}
}
I can't find any one referencing a similar anywhere soo I'm here
Also note if I miss spell my source it tells me off because they don't match the URL, if i include an empty list of data points I get the same error. I'm quite lost so I'm throwing it out there to see if anyone knows what that means
Thanks in advance
edit: i tried changing the hex code for my project's integer code and got an error about untrusted source. so i tried making a new test data source which works as expected. Slightly annoyed but guess I'll just start over..
OK I was stupid and didn't set up my own credentials in the OAuth settings in top right of the dashboard as it said to here. I forgot that bit -_- now I can access my own stream again and it shows my integer project id in the stream id not the hex one
https://developers.google.com/fit/rest/v1/get-started
Now I get invalid argument, but.. whatever >_<
edit 2:
invalid argument was because I have fPVal instead of fpVal and modifiedTimeMillis mills is not supposed to be submitted, obviously

HTTP service API error message best practise

For a error case when calling some HTTP Rest service API, the response is as follows:
{
"statusCode": "400",
"error": "Bad Request",
"message": "Can not construct instance of java.math.BigDecimal from String value 'a': not a valid representation\n at [Source: org.apache.cxf.transport.http.AbstractHTTPDestination$1#2f650e17; line: 1, column: 2] (through reference chain: com.foo.services.dto.request.ItemToUpdate[\"quantity\"])",
"validation": {
"source": "PAYLOAD",
"keys": ["key"]
},
"errorIdentifiers": [],
}
I am wondering if the message field in the response is appropriate. It does reveal certain level of implementation to the end user. Is this considered as
no particular problem at all
just a bad cosmetic issue that won't cause serious problem, just not readable to end user
potential security risk that definitely needs to be fixed
I think that you should only log the stacktrace on the server side. IMO it's technical hints (in addition, perhaps the end user even doesn't use Java to interact with your API) and the only thing that interests the end user of your API is that there is here a validation error within the provided data.
Another remark is that you use the status code and statusmessage within your response payload. I think that you don't need to duplicate this since it's already present in the response.
I would suggest an error message like that:
{
"messages": {
"quantity": "this must be a valid number"
}
}
I use a JSON structure for the field messages since there could be several validation errors within the provided data. Note that it's only a suggestion and you could extend this to your exact needs.
Hope it helps.
Thierry

PAGE_ID/insights/page_fans/lifetime?until=DATE gives OAuthException for some dates

For some of my fanpages, it gives OAuth error , once you try to get data using /PAGE_ID/insights/page_fans/lifetime Facebook API.
What excatly happened was, I used PAGE_ID/insights/page_fans/lifetime?until=2013-05-04. It pulling through data. But if I use PAGE_ID/insights/page_fans/lifetime?until=2013-05-03 , that means same query a day before the first query, it gives
{
"error": {
"message": "An unknown error has occurred.",
"type": "OAuthException",
"code": 1
}
}
Does any have proper explanation for this?
you cannot use date range in /insights/page_fans/lifetime
query it without any parameters
you can combine
/insights/page_fans/lifetime
/insights/page_fan_removes
/insights/page_fan_adds
to get a daily reading