I am trying to implement the stream (news feed) paging function to my app, but it does not work as expected. I found many similar questions here but there are no solutions to solve this problem.
I tried both Graph API and FQL and the behavior was similar. It succeeds to get the result one or two times but after that, it fails to get the result (gets the empty JSON array).
Finally, I found this problem depends on access_token. If I just change the source code to use Android SDK Stream Example App ID rather than my own App ID for authentication, it works perfectly.
So, I believe the Facebook server checks the App ID and returns some weird or restricted access_token to my app.
Are there any condition to get the valid access_token? I tried the exact same permissions with Android SDK Stream example app, but it could not solve the problem.
Will changing the App ID (to get the valid access_token) solve the case?
Verify your app has the read_stream permission. Without it you will not get any non-public objects.
There also seems to be some general LIMIT OFFSET issues with FQL and stream. See Facebook FQL stream limit? and http://developers.facebook.com/bugs/303076713093995.
Try using the SDK on Facebook. Then get the access token.
Use the Facebook SDK for Android. It can be found here. There are getter and setter methods to get and set the access token. The first time you do a single sign-on (SSO), you must save the access token in SharedPreferences and there's no need to reauthenticate again and again.
Just set the access token from your preferences and make a call to the feed dialog. The offline_access permission is to be deprecated. The Facebook SDK for Android does the rest of the work. Just supply sufficient parameters through Bundle.
A couple of things on Android:
get right permissions "read_stream"
Use the android SDK
Check the sample that came w/ android. In the onCreate(), I authenticate Facebook object
this.facebook.authorize(this, new DialogListener() {....}
Test using Facebook's Graph API Explorer.
If you paste in some code I can help you debug further.
The access token returned by Facebook server is valid only for a particular period of time. After which you need to refresh your access token, which is a tedious job.
So, in order to avoid this and maintain your token, you need to add the permission "offline_access" to your permission list. This is the approach used by almost Facebook-related apps.
Related
I have an android and iPhone app, and the apps are getting data
from my website based on some conditions they select on the app.
I created a secured url that is not open to the public (can't be find on our website) and using a hash code that I thought was secure enough. Something like the following
http://test.com/data/get_data.php?key=akl;sd8234
The extra conditions they select in the app will be append as query parameters to the same url.
Base on the condition, the php file will then out data in json format.
However, I discovered recently someone else create the exact same app and actually getting data from my server, and from the secret url that I created. The reason I know is because I change something on that secret get_data.php page and it reflected on their app.
I don't know who they get a hold to my url, is there a way to create a more secure way to pass the data from my web server to the app so others can't steal my data?
You should create an API with Basic Auth or OAuth. You can't rely on your URL because it can be caught in logs.
Check this course out
In addition to shayegh's answer, you need to understand that every endpoint that you access within your application is public by nature. Everyone can access your server's endpoint just as well as your mobile application (created by you) can. However, you can make your server's endpoint protected by adding authorization requirements on your endpoint.
Authorization
There are many authorization protocols out there, OAuth, OAuth2.0, Basic Auth (credentials like email and password), etc. All of these are just ways to grant anyone access to resources in your endpoint. Think of it as a lock on your home door, only someone with a key can go into your house and make a mess.
Please keep in mind that this is a very simplified version of what authorization protocols actually look like, how it actually secures the distribution of access keys/tokens, etc.
Additional questions and answers
I tried to generate log files from my android phone, and I can't seem to find the .php file from the log files. Is that possible for someone to decode the android app or the iphone app so that they can view my source code?
Answer: I would always assume that everything that is happening on client's side (mobile app, WebApp's front end, etc) is beyond my control. That means anyone can access, read, tweak my client applications. With that said, I would assume that it is indeed possible for someone to unravel your android / iPhone app (get the source code) to get your client side keys.
How would this (OAuth/basic) help? Surely the person creating the other app would just add the OAuth/basic auth as well, wouldn't they?
In order for that other person to access the protected endpoint they would need to have access to your access tokens of the original app. On top of that, they would need to do it fast because usually access tokens only lasts for a short period of time.
Will using Basic Auth or OAuth key works if they are able to see my code?
Yes and no, depending on your implementation, attackers might be able to unravel your app and somehow fetch user's credentials or tokens from bad practices.
I want to ask how could I get user's which is logged into app email as string value? I have only seen tutorials how to get it using json and then send it to web service which I don't need. Maybe someone could show me the simple way of getting user email?
The Graph API always returns JSON. So, no, I don't think that this is possible. The Android SDK provides convenience classes, so I don't really see a big effort using those. You can use JSONObject.get("email") to retrieve to value of the email property I guess.
See
https://developers.facebook.com/docs/android/graph#userdata
http://developer.android.com/reference/org/json/JSONObject.html#get(java.lang.String)
I am aware that the Instagram API was down a few hours ago, but it seems to be back up now. The problem is, when we post data to Instagram saying to like a specific photo, we get this error:
{"meta":{"error_type":"APINotAllowedError","code":400,"error_message":"you cannot like this media"}}
We have gotten this error before, but we don't understand why we are getting it. Keep in mind, we logged into an alternate account which means that account hasn't even liked the media yet.
If it helps at all to know, we are running the like command by requesting the url https://api.instagram.com/v1/media/{media-id}/likes with {media-id} being replaced by the image id, and we are including the user's access token in the body of the http request. This is obviously a post request
There is no Instagram documentation on why we would get this message. Does anyone have a solution?
I've run into the same thing and I found that there were three cases where I received this error:
The photo has been deleted. If you are caching media data and trying to like it later this could come up.
The user is private. You can't like a photo if the user is private and they haven't given you permission to follow them.
You've done too much liking with the public API. If you try to like a photo and find that it's neither deleted nor is the user private, then Instagram has put a temporary ban on your account from liking via the api. I'm not sure what triggers this other than excessive liking. You'll need to wait up to a week without making any high-volume likes via that access token for the timeout to expire (although you can to a test every once in a while to see if this timeout has expired).
I'm trying to retrieve the people in a user's circle that have installed the current application.
I have used the sample application "PlusSampleActivity" provided in the SDK and successfully managed to get the list of all people in the user's circles.
However, I'm not sure how to get if the person have installed the application or not. The documentation available seems to be very limited...
What I have found is
https://developer.android.com/reference/com/google/android/gms/plus/model/people/Person.html
I'm using below function but this is always returning false. (I have created a user that have installed the app and I can see this when visiting the user's profile on the web using Google+)
Is there some other API that should be used? Or some way to debug this better?
public abstract boolean isHasApp ()
If "true", indicates that the person has installed the app that is
making the request and has chosen to expose this install state to the
caller. A value of "false" indicates that the install state cannot be
determined (it is either not installed or the person has chosen to
keep this information private).
UPDATED
Seems like the hasapp field is not even included in the response?
When trying the API on below link, I never succeed to have the hasapp included in the response... Any suggestions what I might be doing wrong??
https://developers.google.com/apis-explorer/#p/plus/v1/plus.people.get
(I posted the same question on Google groups, here)
Unfortunately, the hasApp field doesn't get filled in the response - it's actually a legacy field from an older API. The best way of matching is to keep track of installed users in your database with their Google IDs, and compare that to the IDs in the people.list response.
The documentation should be updated to reflect this soon, sorry for the confusion!
The new Facebook SDK for Android (3.0) has deprecated a lot of the old methods, including the setAccessToken method. The replacement for this (I think) is the method openWithImportedAccessToken
https://developers.facebook.com/docs/reference/android/3.0/Session#openWithImportedAccessToken(String, Date, Date, AccessTokenSource, List, StatusCallback).
Does anyone have any examples of using this? In particular how do you get the expiration time and last refresh time of the access token?
If you have no data for a particular parameter, there are reasonable defaults you can fill in here that result in sub-optimal-but-not-too-bad behavior.
Keep in mind that you should only be calling this API the first time you run after upgrading to the 3.x Android SDK to import the token from wherever you were storing it before. Afterwards, the SDK manages the token cache by default. So any sub-optimal behavior should be one-time localized to this upgrade.
Provide what data you know. For what you don't know, it is mostly okay to specify that:
the expiration date is 60 days from now
the last updated time is now
the AccessTokenSource is FACEBOOK_APPLICATION
the permission list is empty
Note that if you always ask for the same permissions and therefore know what permissions your old token has, use those.
It is better if you can provide the correct values for these parameters, but the downsides are generally not terrible. Here are the downsides to lying to this API:
Downside of specifying that the expiration time is later than it is: if the token is expired, you may make a request anyway and have the Facebook service return an error rather than noticing it immediately on the client side.
Downside of specifying that the last updated time is more recent than it was: the SDK will try to refresh the token on the first request rather than waiting for 24 hours.
Downside of specifying AccessTokenSource as FACEBOOK_APPLICATION: if the token came from a WebView, the SDK will try to refresh your token, and the operation will fail. Eventually the token will expire, and the subsequent login will correct the AccessTokenSource value.
Downside of specifying empty permissions: when you are about to perform an operation, you should check if you have permissions to do the operation, and if not you should call Session.reauthorize() to request permissions. If you call openWithImportedAccessToken() with an empty list (or fewer permissions that you actually have), then you will think you do not have the permission and will ask the user again for the permission. As long as this is in the context of the user doing an operation where this permission is expected, this should not be too jarring to the user.
Our documentation here tells you how to to retrieve/debug the access token to retrieve metadata such as the expiration and when it was issued. You can use this endpoint if you do not those fields beforehand.