List of user_friends is empty Facebook SDK 3.14.1 - facebook-graph-api-v2.0

With this code i want to extract a list of my Friends and as next step all of the last checkins of my friends but the list is always empty.
public void onClick(View v) {
String fqlQuery = "SELECT uid,name,pic_square FROM user WHERE uid IN "
+ "(SELECT uid2 FROM friend WHERE uid1 = me() LIMIT 25)";
Bundle params = new Bundle();
params.putString("q", fqlQuery);
Session session = Session.getActiveSession();
Request request = new Request(session, "/fql", params, HttpMethod.GET, new Request.Callback() {
public void onCompleted(Response response) {
Log.i(TAG, "Result: " + response.toString());
try {
GraphObject graphObject = response.getGraphObject();
JSONObject jsonObject = graphObject.getInnerJSONObject();
Log.d("data", jsonObject.toString());
JSONArray array = jsonObject.getJSONArray("data");
System.out.println("länge array" + array.length());
for (int i = 0; i < array.length(); i++) { //
JSONObject friend = array.getJSONObject(i);
Log.d("uid", friend.getString("uid"));
Log.d("name", friend.getString("name"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Request.executeBatchAsync(request);
}
});
return view;
}
}
also i want to get all checkins of my friends but the data is empty
I would happy if someone could help me out
Output of LogCat:
{ "data": []}

As of Facebook API v2.0, friends list (/me/friends and FQL equivalent) returns ONLY user's friends who use your application. This limitation applies to apps that are on v1.0 mode too.
If you're looking to get friends for tagging actions: https://developers.facebook.com/docs/graph-api/reference/v2.0/user/taggable_friends
If you're looking to get friends for inviting to a GAME: https://developers.facebook.com/docs/graph-api/reference/v2.0/user/invitable_friends
Cheers!

Related

How to verify two Images using Azure Cognitive Face API ? Need Sample Code

How to verify two Images using Azure Cognitive Face API ? Need Sample Code
I have two images of a single person. Now I want to compare those images and check whether those images are of same person or not. From the documentation I came to know that, I have to send two faceid's along with the url. I tried that, but it is not working. May be, I am missing something. Please help me for the same & provide me some sample code for the same if possible.
Waiting for your response.
Try the console app code below :
using Microsoft.Azure.CognitiveServices.Vision.Face;
using Microsoft.Azure.CognitiveServices.Vision.Face.Models;
using System;
using System.IO;
using System.Linq;
using System.Threading;
namespace FaceIdentityTest
{
class Program
{
static void Main(string[] args)
{
string persionPicPath = #"<some path>\personPic.jpg";
String[] picsPath = { #"<some path>\pic1.jpg", #"<some path>\pic2.jpg" };
string endpoint = #"https://<your endpoint name>.cognitiveservices.azure.com/";
string subscriptionKey = "<your subscription key>";
IFaceClient faceClient = new FaceClient(
new ApiKeyServiceClientCredentials(subscriptionKey),
new System.Net.Http.DelegatingHandler[] { });
faceClient.Endpoint = endpoint;
// Create an empty PersonGroup
Console.WriteLine("create person group");
string personGroupId = "demogroup";
faceClient.PersonGroup.CreateAsync(personGroupId, "demo group").GetAwaiter().GetResult();
// Define a person named Bill
Console.WriteLine("create a person in group");
var createPersonResult = faceClient.PersonGroupPerson.CreateAsync(
// Id of the PersonGroup that the person belonged to
personGroupId,
// Name of the person
"Bill"
).GetAwaiter().GetResult();
//Add a face to Bill
Console.WriteLine("Add a face to person");
using (Stream s = File.OpenRead(persionPicPath))
{
// Detect faces in the image and add to Anna
faceClient.PersonGroupPerson.AddFaceFromStreamAsync(
personGroupId, createPersonResult.PersonId, s).GetAwaiter().GetResult();
}
//Train person group
Console.WriteLine("start train person group...");
faceClient.PersonGroup.TrainAsync(personGroupId).GetAwaiter().GetResult();
//Check train status
TrainingStatus trainingStatus = null;
while (true)
{
trainingStatus = faceClient.PersonGroup.GetTrainingStatusAsync(personGroupId).GetAwaiter().GetResult();
if (trainingStatus.Status != TrainingStatusType.Running)
{
break;
}
else {
Console.WriteLine("trainning person group...");
}
Thread.Sleep(1000);
}
foreach (var pic in picsPath) {
Console.WriteLine("start identify faces in :" + pic);
using (Stream s = File.OpenRead(pic))
{
var faces = faceClient.Face.DetectWithStreamAsync(s).GetAwaiter().GetResult();
var faceIds = faces.Select(face => (Guid)face.FaceId).ToList();
var results = faceClient.Face.IdentifyAsync(faceIds, personGroupId).GetAwaiter().GetResult();
foreach (var identifyResult in results)
{
Console.WriteLine("Result of face: {0}", identifyResult.FaceId);
if (identifyResult.Candidates.Count == 0)
{
Console.WriteLine("No one identified");
}
else
{
// Get top 1 among all candidates returned
var candidateId = identifyResult.Candidates[0].PersonId;
var person = faceClient.PersonGroupPerson.GetAsync(personGroupId, candidateId).GetAwaiter().GetResult();
Console.WriteLine("Identified as {0}", person.Name);
}
}
}
}
Console.ReadKey();
}
}
}
My pics :
Result :
Btw, no matter which programming language you are using , just follow the steps in this demo will be able to use Face API to identify faces .
Hope it helps .
You can import Microsoft.Azure.CognitiveServices.Vision.Face here in VS :

AsyncTask doInBackground() does not execute correctly on run, but works on debugger

#Override
protected ArrayList<HashMap<String, String>> doInBackground(Void... params) {
ArrayList<HashMap<String, String>> PLIST = new ArrayList<>();
HttpHandler sh = new HttpHandler();
String jsonStr = sh.makeServiceCall(jsonUrl);
ArrayList<String> URLList = new ArrayList<>();
if (jsonStr != null) {
placesList.clear();
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
JSONArray placesJsonArray = jsonObj.getJSONArray("results");
String pToken = "";
// looping through All Places
for (int i = 0; i < placesJsonArray.length(); i++) {
JSONObject placesJSONObject = placesJsonArray.getJSONObject(i);
String id = placesJSONObject.getString("id");
String name = placesJSONObject.getString("name");
HashMap<String, String> places = new HashMap<>();
// adding each child node to HashMap key => value
places.put("id", id);
places.put("name", name);
PLIST.add(places);
}
//TODO: fix this...
if (SEARCH_RADIUS == 1500) {
Log.e(TAG, "did it get to 1500?");
try {
for (int k = 0; k < 2; k++) {
//error is no value for next_page_token... this
ERROR HERE
pToken = jsonObj.getString("next_page_token"); //if I place breakpoint here, debugger runs correctly, and returns more than 20 results if there is a next_page_token.
String newjsonUrl = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location="
+ midpointLocation.getLatitude() + "," + midpointLocation.getLongitude()
+ "&radius=" + SEARCH_RADIUS + "&key=AIzaSyCiK0Gnape_SW-53Fnva09IjEGvn55pQ8I&pagetoken=" + pToken;
URLList.add(newjsonUrl);
jsonObj = new JSONObject(new HttpHandler().makeServiceCall(newjsonUrl)); //moved
Log.e(TAG, "page does this try catch");
}
}
catch (Exception e ) {
Log.e(TAG, "page token not found: " + e.toString());
}
for (String url : URLList){
Log.e(TAG, "url is : " + url);
}
I made an ArrayList of URLS after many attempts to debug this code, I planned on unpacking the ArrayList after all the urls with next_page_tokens were added, and then parsing through each of them later. When running the debugger with the breakpoint on pToken = getString("next_page_token") i get the first url from the Logger, and then the second url correctly. When I run as is, I get the first url, and then the following error: JSONException: No value for next_page_token
Things I've tried
Invalidating Caches and restarting
Clean Build
Run on different SDK versions
Made sure that the if statement is hitting (SEARCH_RADIUS == 1500)
Any help would be much appreciated, thanks!
Function is called in a listener function like this.
new GetPlaces(new AsyncResponse() {
#Override
public void processFinish(ArrayList<HashMap<String, String>> output) {
Log.e(TAG, "outputasync:" );
placesList = output;
}
}).execute();
My onPostExecute method.
#Override
protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
delegate.processFinish(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
}
It turns out that the google places api takes a few milliseconds to validate the next_page_token after it is generated. As such, I have used the wait() function to pause before creating the newly generated url based on the next_page_token. This fixed my problem. Thanks for the help.

Google+ unable to insert moment - A Year and 6 Revisions After

NOTE: Using the Sign-in button is NOT an option
A year ago I was having a problem creating a moment. Back then I was using version 1.2 of the Google+ API .Net client. As I described in this post, I had it working although the code failed to insert a moment from time to time. I was hoping that the process is more stable and easier to implement now, and it seems like it as can be seen in the example that you can download here - the current version as of this writing is v1.8. So I created a simple project following the SimpleOAuth2 sample in the download, but implementing Google+. This is the code I came up:
public partial class _Default : System.Web.UI.Page
{
private PlusService service;
// Application logic should manage users authentication.
// This sample works with only one user. You can change
// it by retrieving data from the session.
private const string UserId = "user-id";
protected void Page_Load(object sender, EventArgs e)
{
GoogleAuthorizationCodeFlow flow;
var assembly = Assembly.GetExecutingAssembly();
using (var stream = assembly.GetManifestResourceStream(
"GPlusSample.client_secrets.json"))
{
flow = new GoogleAuthorizationCodeFlow(
new GoogleAuthorizationCodeFlow.Initializer
{
DataStore = new FileDataStore("GPlusSample.Store"),
ClientSecretsStream = stream,
//
// Tried only this scope but it did not work
//Scopes = new[] { PlusService.Scope.PlusMe }
//
// I tried the following: but did not work either
//Scopes = new[] { PlusService.Scope.PlusMe,
// "https://www.googleapis.com/auth/plus.moments.write" }
//
// I tried this as well and it failed
//Scopes = new[] { PlusService.Scope.PlusLogin }
//
// Maybe this... but still no joy
Scopes = new[] { PlusService.Scope.PlusLogin,
PlusService.Scope.PlusMe }
});
}
var uri = Request.Url.ToString();
var code = Request["code"];
if (code != null)
{
var token = flow.ExchangeCodeForTokenAsync(UserId, code,
uri.Substring(0, uri.IndexOf("?")), CancellationToken.None).Result;
// Extract the right state.
var oauthState = AuthWebUtility.ExtracRedirectFromState(
flow.DataStore, UserId, Request["state"]).Result;
Response.Redirect(oauthState);
}
else
{
var result = new AuthorizationCodeWebApp(flow, uri, uri)
.AuthorizeAsync(UserId, CancellationToken.None).Result;
if (result.RedirectUri != null)
{
// Redirect the user to the authorization server.
Response.Redirect(result.RedirectUri);
}
else
{
// The data store contains the user credential,
// so the user has been already authenticated.
service = new PlusService(new BaseClientService.Initializer
{
ApplicationName = "Plus API Sample",
HttpClientInitializer = result.Credential
});
}
}
}
/// <summary>Gets the TasksLists of the user.</summary>
public async System.Threading.Tasks.Task InsertMoment()
{
try
{
var me = service.People.Get("me").Execute();
var request = service.Moments.Insert(new Moment()
{
Target = new ItemScope {
Id=Guid.NewGuid().ToString(),
Image="http://www.google.com/s2/static/images/GoogleyEyes.png",
Type="",
Name = "test message",
Description="test",
Text="test message",
},
Type = "http://schemas.google.com/AddActivity",
}, me.Id, MomentsResource.InsertRequest.CollectionEnum.Vault);
var response =await request.ExecuteAsync();
output.Text = "<h1>" + response.Id + "</h1>";
}
catch (Exception ex)
{
var str = ex.ToString();
str = str.Replace(Environment.NewLine, Environment.NewLine + "<br/>");
str = str.Replace(" ", " ");
output.Text = string.Format("<font color=\"red\">{0}</font>", str);
}
}
protected async void createMomentButton_Click(object sender, EventArgs e)
{
await InsertMoment();
}
}
That code always give me a 401 Unauthorized error, even if I have the Google+ API turned on for my project. Here's the actual error I got:
The service plus has thrown an exception: Google.GoogleApiException:
Google.Apis.Requests.RequestError Unauthorized [401] Errors [
Message[Unauthorized] Location[ - ] Reason[unauthorized]
Domain[global] ]
It's interesting to see that the insert moment is failing even though the call to People.Get("me") works - get("me") works with all of the scope combinations I listed above. It's important to note that each time I try a new scope, I first log out of my Google account and delete the access token that is stored in GPlusSample.Store.
EDIT
I tried setting just the Url instead of individual items as suggested by Ian and I got the exact same error.
var request = service.Moments.Insert(new Moment()
{
Target = new ItemScope {
Url = "https://developers.google.com/+/web/snippet/examples/thing"
},
Type = "http://schemas.google.com/AddActivity",
}, me.Id, MomentsResource.InsertRequest.CollectionEnum.Vault);
var response =await request.ExecuteAsync();
https://www.googleapis.com/auth/plus.login is the right scope for writing moments, but you need to have requested the specific app activity types you want to write as well. The parameter for this is request_visible_actions, and it takes a space separated list of arguments of the types (Listed on https://developers.google.com/+/api/moment-types/ - e.g. http://schemas.google.com/AddActivity).
The client library may not have a method for adding request_visible_actions, so you may have to add it on to the auth URL you redirect the user to manually (remember to URLencode the app activity type URLs!)

Facebook SDK for Android request error

I use Facebook SDK for Android 3.0
I want to get the user's photos and show in my app.
Reference document, login was a success.
and I try to get the album.
I tried two methods fql and graph api.
graph_or_fql = "fql";
if (graph_or_fql.equals("fql")) {
String query = "SELECT aid, cover_pid, name, size, visible, object_id FROM album WHERE owner = "
+ userId;
Bundle params = new Bundle();
params.putString("method", "fql.query");
params.putString("query", query);
mAsyncRunner.request(null, params,
new PhotosRequestListener());
} else {
// Bundle params = new Bundle();
// params.putString("fields", "name, aid, size");
// mAsyncRunner.request("me/photos", params,
// new PhotosRequestListener());
mAsyncRunner.request("me/album",
new PhotosRequestListener());
}
/*
* callback after friends are fetched via me/friends or fql query.
*/
public class PhotosRequestListener extends BaseRequestListener {
#Override
public void onComplete(final String response, final Object state) {
dialog.dismiss();
Log.d("tag", "response: " + response);
try {
if (graph_or_fql.equals("fql")) {
jsonArray = new JSONObject(response).getJSONArray("data");
// jsonArray = new JSONArray(response);
// JSONObject jsonObj = new JSONObject(response);
// jsonArray = new JSONArray(jsonObj.getString("data"));
} else {
jsonArray = new JSONObject(response).getJSONArray("data");
}
} catch (JSONException e) {
showToast("JSONError: " + e.getMessage());
e.printStackTrace();
return;
}
gridView.setOnItemClickListener(MainActivity.this);
gridView.setAdapter(new GridViewAdapter(MainActivity.this));
}
public void onFacebookError(FacebookError error) {
dialog.dismiss();
Toast.makeText(getApplicationContext(),
"Facebook Error: " + error.getMessage(), Toast.LENGTH_SHORT)
.show();
}
}
But all error.
fql error message: "error_msg":"Session key invalid or no longer valid"
11-07 16:41:10.956: D/tag(468): response: {"error_code":102,"error_msg":"Session key invalid or no longer valid","request_args":[{"key":"query","value":"SELECT aid, cover_pid, name, size, visible, object_id FROM album WHERE owner = 100001791736733"},{"key":"method","value":"fql.query"},{"key":"format","value":"json"}]}
11-07 16:41:10.956: W/System.err(468): org.json.JSONException: No value for data
11-07 16:41:10.966: W/System.err(468): at org.json.JSONObject.get(JSONObject.java:354)
11-07 16:41:11.015: W/System.err(468): at org.json.JSONObject.getJSONArray(JSONObject.java:544)
11-07 16:41:11.015: W/System.err(468): at com.example.facebookphoto.MainActivity$PhotosRequestListener.onComplete(MainActivity.java:144)
11-07 16:41:11.015: W/System.err(468): at com.facebook.android.AsyncFacebookRunner$2.run(AsyncFacebookRunner.java:273)
graph api error message: "error":{"message":"An active access token must be used to query information about the current user.","type":"OAuthException","code":2500}
11-07 16:45:43.106: D/tag(538): response: {"error":{"message":"An active access token must be used to query information about the current user.","type":"OAuthException","code":2500}}
11-07 16:45:43.106: W/System.err(538): org.json.JSONException: No value for data
11-07 16:45:43.156: W/System.err(538): at org.json.JSONObject.get(JSONObject.java:354)
11-07 16:45:43.156: W/System.err(538): at org.json.JSONObject.getJSONArray(JSONObject.java:544)
11-07 16:45:43.176: W/System.err(538): at com.example.facebookphoto.MainActivity$PhotosRequestListener.onComplete(MainActivity.java:149)
11-07 16:45:43.176: W/System.err(538): at com.facebook.android.AsyncFacebookRunner$2.run(AsyncFacebookRunner.java:273)
I don't get it, because what causes. help me, thanks.

Create Registrant using GoToWebinar

I want to create a registrant for a webinar using GoToWebinar API's. I came across the code at gotowebinar api php
I provided my username and password to get the oAuth object. This worked perfectly fine as described.
Now I want to do something like this:
I have a Registration page. When user fills in the required details, selects the 'register to webinar' option and clicks on 'Submit', I want to enrol him for that webinar using CreateRegistrant API. The problem is, I am not able to get the oAuth object without providing username and password. Is there a way to pass this programatically and create oAuth object?
I store my API key, UserID and password in my WebConfig then read them into a Login Object for use when I do authorization. Here's how I do it in C#:
public class Login
{
public string UserId
{ get { return System.Configuration.ConfigurationManager.AppSettings["GTWUserId"]; } }
public string Password
{ get { return System.Configuration.ConfigurationManager.AppSettings["GTWPassword"]; } }
public string APIKey
{ get { return System.Configuration.ConfigurationManager.AppSettings["GTWAPIKey"]; } }
}
public string DoAuthorize()
{
Login lg = new Login();
string sError = "";
// first we need to create the uri for the web request
string uri = String.Format("https://api.citrixonline.com/oauth/access_token?grant_type=password&user_id={0}&password={1}&client_id={2}",
lg.UserId, lg.Password, lg.APIKey);
// then the request to login is created and sent. From the response
// we need to store at least the access token and the organizer key
// to use for further calls
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Accept = "application/json";
request.ContentType = "application/json";
try
{
var response = request.GetResponse();
//the following lines duplicate the response stream so we can read it for
//deserialization and also re-read it and write it out.
using (MemoryStream ms = new MemoryStream())
{
var stream = response.GetResponseStream();
stream.CopyTo(ms);
ms.Position = 0;
stream.Close();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ResponseDirectLogin));
var deserialized = (ResponseDirectLogin)ser.ReadObject(ms);
auth.OauthToken = deserialized.AccessToken;
auth.OrganizerKey = deserialized.OrganizerKey;
}
}
catch (WebException e)
{
using (var sr = new StreamReader(e.Response.GetResponseStream()))
sError = sr.ReadToEnd();
sError = String.Concat(sError, "/n", uri);
}
return sError;
}
public class Auth {
public string OauthToken { get; set; }
public string OrganizerKey { get; set; }
}
public static Auth auth = new Auth(); // This is actually in a BaseControlelr inherited by our MVC Home Controller.
public string DoRegister(string WebinarKey)
{
// Here we authorize if we haven't alerady
if (auth.OauthToken == null)
{
sMessage = DoAuthorize();
}
// first we need to create the uri for the web request
// OrganizerKey is your authorization key for the webinar organizer
string uri = String.Format(#"https://api.citrixonline.com/G2W/rest/organizers/{0}/webinars/{1}/registrants",
OrganizerKey, WebinarKey);
//then create and serialize the registrant object
// This is for when you have questions on your webinar, you can omit them if you don't have any
List<questions> q = GetQuestionKeys(Key, OrganizerKey);
List<response> responses_ = new List<response>();
foreach (var question in q)
{
response res1 = new response();
res1.questionKey = question.questionKey;
// determine which question and set the response
if (question.question == "question")
{
res1.responseText = "response";
responses_.Add(res1);
}
}
var registrant = new Registrant
{
firstName = FirstName,
lastName = LastName,
email = EmailAddress,
responses = responses_.ToArray()
};
JavaScriptSerializer ser = new JavaScriptSerializer();
string json = ser.Serialize(registrant);
// then the request to create a registrant is created and sent
// N.B. we need to include the access token to the headers to access
// the user's account and data
try {
WebClient client = new WebClient();
client.Headers = new WebHeaderCollection();
client.Headers.Add("Accept", "application/vnd.citrix.g2wapi-v1.1+json");
client.Headers.Add("Content-type", "application/json");
client.Headers.Add("Authorization", string.Format("OAuth oauth_token={0}", OAuthToken));
try
{
string resp = client.UploadString(uri, "POST", json);
var ok = ser.Deserialize<ResponseCreateRegistrantOk>(resp);
}
catch (WebException e)
{
//if there is an error, e.g. the registrant exists already
// we need an alternative deserialization
Stream s = new MemoryStream();
using (Stream response = e.Response.GetResponseStream())
{
byte[] buffer = new byte[1024];
int byteCount;
do
{
byteCount = response.Read(buffer, 0, buffer.Length);
s.Write(buffer, 0, byteCount);
} while (byteCount > 0);
}
s.Seek(0, SeekOrigin.Begin);
string content = new StreamReader(s, Encoding.UTF8).ReadToEnd();
s.Seek(0, SeekOrigin.Begin);
using (var err = new StreamReader(s))
{
var sb = new StringBuilder("Registration Error\n");
if (content.IndexOf("int_err_code") > -1)
{
var dupe = ser.Deserialize<ResponseCreateRegistrantDuplicate>(err.ReadToEnd());
sb.AppendFormat(String.Format("Error Code: {0}<br />", dupe.ErrorCode));
sb.AppendFormat(String.Format("Message: {0}<br />", dupe.Message));
}
else
{
var dupe = ser.Deserialize<ResponseCreateRegistrantDuplicate>(err.ReadToEnd());
sb.AppendFormat(String.Format("Description: {0}<br />", dupe.Description));
//sb.AppendFormat(String.Format("Incident: {0}<br />", dupe.Incident));
//sb.AppendFormat(String.Format("Registrant key: {0}<br />", dupe.RegistrantKey));
sb.AppendFormat(String.Format("Join Url: {0}<br />", dupe.JoinUrl));
}
sMessage = sb.ToString();
}
}
} catch (Exception exc) {
exc.Data.Add("stringInfo", "inside");
return "";
}
return sMessage;
}