Posting to Facebook specific friend list using Facebook android SDK - android

I am successfully posting to Facebook wall, but I want that user can choose whether they want to post it to some specific friend list e.g. Acquaintances, Family etc
My code is giving this error :
{"error":{"message":"(#100) privacy must contains a valid privacy 'value'","type":"OAuthException"}}
I have added "privacy" attribute and have given it value of "Family", but its not working, but if I remove the privacy attribute, the wall post is successful
try
{
Bundle parameters = new Bundle();
parameters.putString("message", msg);
parameters.putString("description", "Test 1");
JSONObject jsonObject = new JSONObject();
jsonObject.put("value", "Family");
parameters.putString("privacy", jsonObject.toString());
response = Data.facebook.request("me/feed", parameters,"POST");
} catch(Exception e) {
e.printStackTrace();
}

The value field may specify one of the following strings:
EVERYONE, ALL_FRIENDS, NETWORKS_FRIENDS, FRIENDS_OF_FRIENDS, CUSTOM .
The friends field must be specified if value is set to CUSTOM and
contain one of the following strings: EVERYONE, NETWORKS_FRIENDS (when
the object can be seen by networks and friends), FRIENDS_OF_FRIENDS,
ALL_FRIENDS, SOME_FRIENDS, SELF, or NO_FRIENDS (when the object can be
seen by a network only).
The allow field must be specified when the friends value is set to
SOME_FRIENDS and must specify a comma-separated list of user IDs and
friend list IDs that 'can' see the post.
Try this instead, but you will need to know the friendlists ID for Family.
var theFriendLists = Api.Get(`me/friendlist`);
var theFriendsListIdForFamily = theFriendLists.Select item where list_type=="family";
JSONObject jsonObject = new JSONObject();
jsonObject.put("value", "CUSTOM");
jsonObject.put("friends", "SOME_FRIENDS");
jsonObject.put("allow", theFriendsListIdForFamily);
parameters.putString("privacy", jsonObject.toString());

Related

Validate GET JSON response for login screen and go to home screen

When user login to the app I am getting JSON response with username, pasword, token, userID and onboarding. As per the requirement of the application I hava to redirect the user to home page if this onboarding value is "true" in the JSON data.
[
{
"display_name": "my email ID",
"msg_status": "success",
"userid": "userID",
"plan_type": "none",
"token": "my token",
"requires_onboarding": true
}
]
I get all these fields in my java code. Now I want to let user go to the home screen if this onboarding value is true.
Please help.
If you get this json as a String, parse it like the following code. IF you are already with a JSONArray, then you won't need to use the first line.
JSONArray jsonArray = new JSONArray(jsonString);
JSONObject json2 = jsonArray.get(0);
boolean onBoarding = json2.getBoolean("requires_onboarding");
Then you can do whatever you want with your boolean variable.
If you have questions about JSON, here's a little information about it:
JSONArray is something like: events:[ {"object1": value}, {"object1":Value} ]
Which means that you get the JSONArray and use jsonArray.get(position) for each thing inside it. (Note that you can have JSONArrays inside JSONArrays.
JSONObject is basically the "string" name with a value attached.
So you'll always have to see how the data you're getting is structured to parse right and choose correctly between JSONObjects or Arrays.
Here is a complete explanation the difference.
Simplest way to do this:
boolean what = false;
try{
JSONArray mRootArray = new JSONArray(jsonString);
JSONObject jInnerObject = mRootArray.getJSONObject(0);
what = jInnerObject.getBoolean("requires_onboarding");
}catch(Exception e){
what = false;
e.printstacktrace();
}
Now maintain as per state of boolean:
if(what){
// Go to netxt screen
}else{
// Stay here
}
Hope this will help you,
I got the required output guys thank you for your response it is as I mentioned below.
String name = list.get(5);
if (name.equals("true"))
startActivity(new Intent(Login.this, OnBoardingOne.class));

me/friends empty friend list

I am trying to get friend list using me/frineds tag. There is no user of the app so far so i have added some frirneds as a tester of the app. But they are not showing in the response i am getting empty data list. Please guide me what i am doing wrong here. Here is the code
Bundle required = new Bundle();
required.putString("fields", "id, name, picture.type(square), gender, email");
//Request for friendlist from facebook
Request req = new Request(session, "me/friends", required, HttpMethod.GET,
new Callback() {
#Override
public void onCompleted(Response response)
{
is2=response.getGraphObject();
JSONObject json = is2.getInnerJSONObject();
readResponse(json);
String str = json.toString();
saveFileOnSD("data", str);
// generateNoteOnSD("frinedresponse", str);
Log.v(TAG, str);
}
});
Request.executeBatchAsync(req);
With v2.0, only users who are using the App too show up in the friend list. It is not enough to add someone as Tester in the App Settings, a user has to authorize your App.
See changelog for more information: https://developers.facebook.com/docs/apps/changelog
There is also "invitable_friends" and "taggable_friends", the first one is for game invitations only and the second one is for tagging only.
This has been previously asked, and the thread listed below has a ton of details. The only work around is if your app is a game. Here is the link to the other post: Facebook Graph Api v2.0+ - /me/friends returns empty, or only friends who also use my app

protect http request using json (android)

I am using json request for logging in and displaying messages pertaining to the user .But if I make the same request from the browser it still works. I am using PHP-MYSQL for my App .
I do not have any website so I will need the answer for the app itself.
I am using facebook sdk with android app so I dont have any passwords. I would like to secure the chat msgs between the users and user data profile when it is called.Thats it.
My questions are:
How do I make sure the call is made within the app only?
How do I secure the call when some tries to copy and paste the code in the browser ?
3.Have timeout for the message created after 10 secs.So the same url and msg cannot be reused.
I have http call like http:/example.com/login=emailId;
get msgs: http:/example.com/getMsgs/user=uiniqueNo;
I have provided the above links as I am using in the app and its working fine but is not secure.
Please suggest me some documents and process.I have checked this link Protect HTTP request from being called by others but it was not clear .Please suggest me any tutorial which has the above requirements . Thanks in Advance.I really appreciate the help.
public class CustomizedListView extends Activity {
// All static variables
static final String URL = "http://example.com/getmsgs/userno=123";
// XML node keys
static final String KEY_SONG = "song"; // parent node
static final String KEY_ID = "id";
static final String KEY_TITLE = "title";
static final String KEY_ARTIST = "artist";
static final String KEY_DURATION = "duration";
static final String KEY_THUMB_URL = "thumb_url";
ListView list;
LazyAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();
JSONObject json = JSONfunctions.getJSONfromURL(URL);
try {
JSONObject arr2 = json.getJSONObject("feed");
JSONArray arr = arr2.getJSONArray("entry");
for (int i = 0; i < arr.length(); i++) {
JSONObject e1 = arr.getJSONObject(i);
JSONArray arr3 = e1.getJSONArray("im:image");
JSONObject arr8 = e1.getJSONObject("im:name");
JSONObject arr10 = e1.getJSONObject("im:artist");
JSONObject e12 = arr3.getJSONObject(0);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
map.put(KEY_THUMB_URL, e12.getString("label"));
map.put(KEY_ARTIST, arr8.getString("label"));
map.put(KEY_TITLE, arr10.getString("label"));
// adding HashList to ArrayList
songsList.add(map);
}
} catch (JSONException e) {
// Log.e("log_tag", "Error parsing data "+e.toString());
Toast.makeText(getBaseContext(),
"Network communication error!", 5).show();
}
list=(ListView)findViewById(R.id.list);
// Getting adapter by passing xml data ArrayList
adapter=new LazyAdapter(this, songsList);
list.setAdapter(adapter);
// Click event for single list row
list.setOnItemClickListener(new OnItemClickListener() {
#SuppressWarnings("unchecked")
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
HashMap<String, String> o = (HashMap<String, String>) list.getItemAtPosition(position);
Toast.makeText(CustomizedListView.this, "ID '" + o.get("KEY_TITLE") + "' was clicked.", Toast.LENGTH_SHORT).show();
}
});
}
}
In the above code anyone can guess usersno but how do I secure that no 123 in the app and in the php server .So that even if sniffer program is used and and reverse engineered to get code from apk file the data still is protect and encryption should be deep in OS which users cannot break and hence I can decrypt the code in server php and user will have no way to randomly type anything as 123.
<?php
$strno=$_GET['strno'];
if (isset($strno))
{
$connect=mysql_connect("localhost","test","test") or die ('Connection error!!!');
mysql_select_db("test") or die ('Database error!!!');
$query=mysql_query("select sno FROM users  where strno='$strno';");
while($row = mysql_fetch_assoc($query))
{
$jsonoutput='{"json":{
"msg_sub":"'.$row['msg_sub'].'",
}}';
}
}
echo trim($jsonoutput);
mysql_close($connect) or die ('Unable to close connection-error!!!');
}
?>
Ok there is no way to actually perfectly protect this system unless you use https to transmit data between your api and your js client.
This is what you do:
First create a user login system, username/password table on your database side
Next create a form for the user to login
Whenever a user tries to access the api your server will check if it has a session set for that user, they will either have to login or pass an existing session id which will grant them access
Next is to buy an https certificate that will ensure your data is transmitted securely
Now on each request to the api, the server always checks if they user has sent a valid SESSION ID, if not, it will simply redirect them to a login page
This is pretty much the only way you can add security to your system. The most important part is the https cert. Without this, it doesnt matter how good a user/password is, it can still be compromised.
EDIT
Here is some sample code to get you started. This code is not tested and its just there to give you an idea. You can read all about sessions here.
<?php
/*
like I said earlier, you need to have a "login" screen on your app
- when the user clicks login it POSTS the request back here
*/
if(isset($_SESSION['username'])){
//the username is in the session so it means
//theyre already logged in
//not sure what strno is doing but you can do that here
$strno=$_GET['strno'];
if (isset($strno))
{
$connect=mysql_connect("localhost","test","test") or die ('Connection error!!!');
mysql_select_db("test") or die ('Database error!!!');
$query=mysql_query("select sno FROM users where strno='$strno';");
while($row = mysql_fetch_assoc($query))
{
$jsonoutput='{"json":{
"msg_sub":"'.$row['msg_sub'].'",
}}';
}
}
echo trim($jsonoutput);
mysql_close($connect) or die ('Unable to close connection-error!!!');
}else if(isset($_POST) && isset($_POST['username']) && isset($_POST['password'])){
//log them in
//query ur database to see if the user exists
//if you get a row back then store that row in the session like
//note: this is just example code
if(/*user is in database, get the row....*/){
session_start();
$_SESSION['username'] = $row['username'];
}
}else{
die("Access Denied");
}
?>
There are two options to achieve this. First thing is using GET method, you can create a specific params on your server side which you are looking for. For example from your android app you are sending http://www.my-backend.com/api/test_api?my_secure_code=thisIsTestString and server returns the right response, but if you send http://www.my-backend.com/api/test_api?my_secure_code=thatsAnotherString , the param value you are searching for in the request is not thisIsTestString, so you should return error message.
In my opinion the second way to achieve this is better, because using GET is not thats ecure in my opinion.It's easier than using POST. In that case you will have to send my_secure_param as post param, which you can use by typing in your browser (there is still a way to achieve this by browser by installing plugin for post request). So I think the best solution here is to use POST request while connection to back-end sending some hashed string using MD5 or SHA1 (at least that's the way we are securing connection with our server + some more extras).
Edit: Regarding comments, the way you can achieve this is by creating some kind of identification for the specific user on your server, not trusting facebook. It's just a proposal...for example you can get the id user from facebook and create a unique hashed id which you will store in your server and everytime you are sending requests from your app, you have to send that unique id, which will be created in app in the same way used to create it on the server. And you will have to check for that hash everytime someone sends message if that match, if not just return error..and just don't forget, use POST requests instead of GET! There is no way to achieve something like this without changing some codes in your server's backend.

Android Facebook Oauthexception with valid access token

I am trying to communicate with Facebook doing simple things. At the moment I can log a user in and post to their wall as them. But for whatever reason, I can't seem to access public information such as their name. I consistently get this error:
{"error":{"message":"Syntax error \"Expected end of string instead of \"?\".\" at character 4: name?access_token=MYACCESSTOKEN","type":"OAuthException","code":2500}}
Here is the call:
SampleRequestListener srl = new SampleRequestListener();
AsyncFacebookRunner afr = new AsyncFacebookRunner(facebook);
afr.request("http://graph.facebook.com/me?fields=name", (RequestListener)srl);
That call is made within a validated session (in the onComplete portion of the DialogListener for .Authorize). Using my access_token and the exact same string as above I can get the request to work just fine at http://developers.facebook.com/tools/explorer/
The error occurs whilst parsing the response in the RequestListener.onComplete
JSONObject json = Util.parseJson(response);
final String name = json.getString("name");
System.out.println("Hi, my name is " + name);
Thank you for your time. All input is welcomed.
UPDATE *
There are two things going on. In the facebook API, Util.openUrl was appending a "?" between the field name and the access_token (as the answer below pointed out). This seems odd. I wonder if I pulled an old version of the API or something. You would think that would be set up correctly.
Also, I called the method incorrectly:
This:
afr.request("http://graph.facebook.com/me?fields=name", (RequestListener)srl);
Should be:
afr.request("me?fields=name", (RequestListener)srl);
If you are using com.facebook.Request class then just use the following form of constructor: Request(Session session, String graphPath, Bundle parameters, HttpMethod httpMethod, Callback callback) and pass your parameters in "parameters" parameter.
Just like:
if (GlobalApplication.accessToken != null && !GlobalApplication.accessToken.isExpired()) {
/* make the API call */
Bundle b = new Bundle();
b.putString("fields", "id,created_time,description,embed_html,name,source,picture");
new GraphRequest(GlobalApplication.accessToken, "/me/videos",
b, HttpMethod.GET, new GraphRequest.Callback() {
#Override
public void onCompleted(GraphResponse response) {
/* handle the result */
Log.i("", "");
String string = response.toString();
JSONObject object = response.getJSONObject();
JSONArray array = response.getJSONArray();
Log.i("", "");
}
}).executeAsync();
Looks like the actual request being sent is something like
/me?fields=name?access_token=MYACCESSTOKEN
and that of course is wrong; it should be an ampersand before the second parameter and not a question mark.
You’d have to look for the location in the code where the access token is added as parameter. At that point there should be a check for whether this URL already contains a question mark or not before appending the access_token parameter.

Not able to tag photos on facebook using the android sdk

I am using the following code (from sdk examples "Hackbook") to add a tag to a photo after uploading it.
json = Util.parseJson(response);
photo_id = json.getString("id");
String relativePath = photo_id + "/tags/" + Utility.userUID;
Bundle params = new Bundle();
params.putString("x", "25");
params.putString("y", "25");
Utility.mAsyncRunner.request(relativePath, params, "POST", new TagPhotoRequestListener(), null);
However, I sometimes (not always) receive the the response from facebook as "false" instead of "true". Is there a specific reason for this?
Additionally, is there a way to tag the photo while uploading it, instead of making an additional call?

Categories

Resources