Facebook Graph API me/friends returns nothing - javascript

I have an app with Facebook login and the logging in and getting basic profile information works fine. However, when I try to get the Facebook friends (which only returns friends who also use the same app), I get [object Object] from the Facebook API. I have the permissions for friends set (according to the Facebook Developer page of my app).
My code looks like this (I'm using the Phonegap plugin, but the code is similar to the JS version for the Facebook API):
// Login function (permissions included)
var login = function () {
if (!window.cordova) {
var appId = prompt("123456789101112", "");
}
facebookConnectPlugin.login(["email, user_friends"],
// SUCCESS
function (response) {
alert('Login successful!');
},
// FAILURE
function (response) {
alert('Login failed')
}
);
}
// Get the friends
var getFacebookFriends = function() {
facebookConnectPlugin.api("me/friends",
// FAILURE
function(response) {
alert('Retrieving Facebook friends failed');
},
// SUCCESS
function(response) {
alert(JSON.stringify('Facebook friends: ' + response));
});
}
The alert says Facebook friends: [object Object]. I'm sure I have a friend who has also logged in to the app using the same permissions. He doesn't appear on the list, only the empty [object Object]. Why do I get this response and not a list of friends?

It´s not empty, it is a JSON object. You just need to decode it correctly:
alert('Facebook friends: ' + JSON.stringify(response));
You can also just use console.log:
console.log(response);
Just connect your phone to the computer while your App is running and use chrome://inspect to debug it like a website (because that´s what it is).

If you want to define a function, you can just do this:
function name() {
...
}
yes, you can leave that var keyword. Also, you should try this:
function getFacebookFriends() {
facebookConnectPlugin.api('/me/friends', function(response) {
if(response.data) {
$.each(response.data,function(index,friend) {
alert(friend.name + ' - FB ID:' + friend.id);
});
} else {
alert("Unable to return Facebook friends!");
}
});
}

I just Hope if this could help you !!
[FBSDKProfile enableUpdatesOnAccessTokenChange:YES]; in - (void)viewDidLoad Method
- (IBAction)Loginwithfacebookaction:(id)sender
{
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login logOut];
[login logInWithReadPermissions:#[#"public_profile", #"email"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error)
{
// There is an error here.
}
else
{
if(result.token) // This means if There is current access token.
{
// Token created successfully and you are ready to get profile info
[self Method];
}
}
}];
}
-(void)Method {
FBSDKGraphRequest *requestMe = [[FBSDKGraphRequest alloc]initWithGraphPath:#"/me?fields=first_name, last_name, picture, email" parameters:nil];
FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init];
[connection addRequest:requestMe completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if(result)
{
if ([result objectForKey:#"email"]) {
email = [result objectForKey:#"email"];
NSLog(#"Email: %#",[result objectForKey:#"email"]);
[[NSUserDefaults standardUserDefaults] setObject:email forKey:#"useremail"];
}
if ([result objectForKey:#"first_name"]) {
NSLog(#"First Name : %#",[result objectForKey:#"first_name"]);
name = [result objectForKey:#"first_name"];
[[NSUserDefaults standardUserDefaults] setObject:name forKey:#"userNameLogin"];
}
if ([result objectForKey:#"id"])
{
NSLog(#"User id : %#",[result objectForKey:#"id"]);
}
}
}];
[connection start];
}

Related

How to create new property in google analytics using javascript code

This is my first time using analytics api to create new property
I got the below code from here
developers.google.com/analytics/devguides/config/mgmt/v3/mgmtReference/management/webproperties/insert
window.onload = function insertProperty() {
var request = gapi.client.analytics.management.webproperties.insert(
{
'accountId': '123456789',
'resource': {
'websiteUrl': 'http://www.examplepetstore.com',
'name': 'Example Store'
}
});
request.execute(function (response) { console.log(response);});
}
<script src="https://apis.google.com/js/api.js"></script>
when i run the code with valid account id ex:'123456789'
I am getting this error
Uncaught TypeError: Cannot read properties of undefined (reading 'analytics') at insertProperty
what should i do to create new property using this code
The below code is the setup of authorization and rest code
// Replace with your client ID from the developer console.
var CLIENT_ID = '';
// Set authorized scope.
var SCOPES = ['https://www.googleapis.com/auth/analytics.readonly'];
function authorize(event) {
// Handles the authorization flow.
// `immediate` should be false when invoked from the button click.
var useImmdiate = event ? false : true;
var authData = {
client_id: CLIENT_ID,
scope: SCOPES,
immediate: useImmdiate
};
gapi.auth.authorize(authData, function(response) {
var authButton = document.getElementById('auth-button');
if (response.error) {
authButton.hidden = false;
}
else {
authButton.hidden = true;
queryAccounts();
}
});
}
function queryAccounts() {
// Load the Google Analytics client library.
gapi.client.load('analytics', 'v3').then(function() {
// Get a list of all Google Analytics accounts for this user
gapi.client.analytics.management.accounts.list().then(handleAccounts);
});
}
function handleAccounts(response) {
// Handles the response from the accounts list method.
if (response.result.items && response.result.items.length) {
// Get the first Google Analytics account.
var firstAccountId = response.result.items[0].id;
// Query for properties.
queryProperties(firstAccountId);
} else {
console.log('No accounts found for this user.');
}
}
function queryProperties(accountId) {
// Get a list of all the properties for the account.
gapi.client.analytics.management.webproperties.list(
{'accountId': accountId})
.then(handleProperties)
.then(null, function(err) {
// Log any errors.
console.log(err);
});
}
function handleProperties(response) {
// Handles the response from the webproperties list method.
if (response.result.items && response.result.items.length) {
// Get the first Google Analytics account
var firstAccountId = response.result.items[0].accountId;
// Get the first property ID
var firstPropertyId = response.result.items[0].id;
// Query for Views (Profiles).
queryProfiles(firstAccountId, firstPropertyId);
} else {
console.log('No properties found for this user.');
}
}
function queryProfiles(accountId, propertyId) {
// Get a list of all Views (Profiles) for the first property
// of the first Account.
gapi.client.analytics.management.profiles.list({
'accountId': accountId,
'webPropertyId': propertyId
})
.then(handleProfiles)
.then(null, function(err) {
// Log any errors.
console.log(err);
});
}
function handleProfiles(response) {
// Handles the response from the profiles list method.
if (response.result.items && response.result.items.length) {
// Get the first View (Profile) ID.
var firstProfileId = response.result.items[0].id;
// Query the Core Reporting API.
queryCoreReportingApi(firstProfileId);
} else {
console.log('No views (profiles) found for this user.');
}
}
function queryCoreReportingApi(profileId) {
// Query the Core Reporting API for the number sessions for
// the past seven days.
gapi.client.analytics.data.ga.get({
'ids': 'ga:' + profileId,
'start-date': '7daysAgo',
'end-date': 'today',
'metrics': 'ga:sessions'
})
.then(function(response) {
var formattedJson = JSON.stringify(response.result, null, 2);
document.getElementById('query-output').value = formattedJson;
})
.then(null, function(err) {
// Log any errors.
console.log(err);
});
}
// Add an event listener to the 'auth-button'.
document.getElementById('auth-button').addEventListener('click', authorize);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello Analytics - A quickstart guide for JavaScript</title>
</head>
<body>
<button id="auth-button" hidden>Authorize</button>
<h1>Hello Analytics</h1>
<textarea cols="80" rows="20" id="query-output"></textarea>
<script src="https://apis.google.com/js/client.js?onload=authorize"></script>
</body>
</html>
yes i did , when i click on Authorize i got this Error {error: {code: 403, message: "Request had insufficient authentication scopes.",…}}
not sure why..?
The developer hasn’t given you access to this app. It’s currently being tested and it hasn’t been verified by Google
The issue is that your project is still in testing, you need to add users who you want to grant permission to test your app.
Go to google cloud console Under consent screen look for the button that says "add Users" add the email of the user you are trying to run the app with.
Understanding Property, Account, and View in Google Analytics
Your Analytics profile consists of 3 different components. They are account, property, and view (if you’re using Universal Analytics).
Here’s a closer look at each of them:
Account: You should have at least one account to access the analytics report.
Property: A property can be a website or a mobile app that you’d like to track in Google Analytics and has a unique tracking ID.
View: A view is the access point for your reports if you’re using Universal Analytics. For example, within a property you can have different views for viewing all the data for your website, viewing only a specific subdomain, like blog.example.com, or viewing only Google Ads traffic. Views do not exist in Google Analytics 4.

Twitter authentication in Codebird JS

I am very new to integrating social sites into a website. I somewhat managed to integrate Facebook, but I have no idea how to integrate Twitter.
I want to login through a Twitter account, then get the username and some other data from Twitter. I have a consumer key and consumer secret. I'm not sure how to proceed from here, and my Google searches haven't helped so far.
I am trying with codebird js:
$(function() {
$('#twitter').click(function(e) {
e.preventDefault();
var cb = new Codebird;
cb.setConsumerKey("redacted", "redacted");
cb.__call(
"oauth_requestToken",
{ oauth_callback: "http://127.0.0.1:49479/" },
function (reply, rate, err) {
if (err) {
console.log("error response or timeout exceeded" + err.error);
}
if (reply) {
// stores it
cb.setToken(reply.oauth_token, reply.oauth_token_secret);
// gets the authorize screen URL
cb.__call(
"oauth_authorize",
{},
function (auth_url) {
window.codebird_auth = window.open(auth_url);
}
);
}
}
);
cb.__call(
"account_verifyCredentials",
{},
function(reply) {
console.log(reply);
}
);
})
});
But I get
Your credentials do not allow access to this resource
How can I resolve this and get the user data? I am open to using an alternate Twitter implementation.
You cannot call cb._call( "account_verifyCredentials"... there.
The code only has a request token, NOT an access token, which you will only receive after the user authorizes your app (on the Twitter auth popup).
You are using the "callback URL without PIN" method, as documented on the README. So you'll need to implement that example code on your http://127.0.0.1:49479/ page.
Also, this essentially requires that you store the oauth credentials somewhere. In my example below, I've used localStorage.
$(function () {
$('#twitter').click(function (e) {
e.preventDefault();
var cb = new Codebird;
cb.setConsumerKey("CeDhZjVa0d8W02gWuflPWQmmo", "YO4RI2UoinJ95sonHGnxtYt4XFtlAhIEyt89oJ8ZajClOyZhka");
var oauth_token = localStorage.getItem("oauth_token");
var oauth_token_secret = localStorage.getItem("oauth_token_secret");
if (oauth_token && oauth_token_secret) {
cb.setToken(oauth_token, oauth_token_secret);
} else {
cb.__call(
"oauth_requestToken", {
oauth_callback: "http://127.0.0.1:49479/"
},
function (reply, rate, err) {
if (err) {
console.log("error response or timeout exceeded" + err.error);
}
if (reply) {
console.log("reply", reply)
// stores it
cb.setToken(reply.oauth_token, reply.oauth_token_secret);
// save the token for the redirect (after user authorizes)
// we'll want to compare these values
localStorage.setItem("oauth_token", reply.oauth_token);
localStorage.setItem("oauth_token_secret", reply.oauth_token_secret);
// gets the authorize screen URL
cb.__call(
"oauth_authorize", {},
function (auth_url) {
console.log("auth_url", auth_url);
// JSFiddle doesn't open windows:
// window.open(auth_url);
$("#authorize").attr("href", auth_url);
// after user authorizes, user will be redirected to
// http://127.0.0.1:49479/?oauth_token=[some_token]&oauth_verifier=[some_verifier]
// then follow this section for coding that page:
// https://github.com/jublonet/codebird-js#authenticating-using-a-callback-url-without-pin
});
}
});
}
})
});
Also made a JSFiddle

How to implement Typeahead JS for Facebook Friends Search?

I have already seen this question. But that uses the old Bootstrap Typeahead and I'm now trying to use the Typeahead JS for autocomplete of Facebook friends. Well, what I'm trying to do is fetch the friends list from Facebook and use it to fill up input text fields. I'm fetching the facebook friends list using the following lines of code.
FB.login(function(response) {
if (response.authResponse) {
var uid = response.authResponse.userID;
access_token = response.authResponse.accessToken;
//alert('login success');
$.getJSON("https://graph.facebook.com/me/friends?access_token=" + access_token, function(result) {
var friends_list = result;
alert(friends_list.data[0].name);
});
} else {
//alert('not logged in');
location.reload();
}
});
This code is in the login page (/). This works perfectly and alert function displays the name correctly. After this, I want it to use with Typeahead JS for which I need to give the JSON Prefetch URL. The console shows 403 error when I try to use the same URL with Typeahead JS that is in another page /login/landing.
I tried to use it in Typeahead JS like this :
$(document).ready(function() {
$('.example-countries .typeahead').typeahead({
name: 'jsonvar_string',
prefetch: "'https://graph.facebook.com/me/friends?access_token='+access_token",
template: ['<p class="repo-language">{{data{{name}}}}</p>', '<p class="repo-name">{{data{{id}}}}</p>'].join(''),
engine: Hogan
});
});
It didn't work. So, I tried to parse the Javascript variable to get just the friends' name alone and use the JSON object as 'local' parameter in Typeahead like this:
FB.login(function(response) {
if (response.authResponse) {
//alert('Hi there');
var uid = response.authResponse.userID;
access_token = response.authResponse.accessToken;
alert('login success');
$.getJSON("https://graph.facebook.com/me/friends?access_token=" + access_token, function(result) {
var friends_list = result;
var friends_list_length = Object.keys(friends_list.data).length;
var jsonvar = [];
for (var i = 0; i < friends_list_length; i++) {
jsonvar.push(friends_list.data[i].name);
}
jsonvar_string = JSON.stringify(jsonvar);
localStorage.jsonvalue = jsonvar_string;
window.location.href = "/login/landing";
});
} else {
alert('not logged in');
location.reload();
}
});
Even that didn't work. My Facebook's API call returns JSON like this:
{
"data": [
{
"name": "ABCD",
"id": "1234455"
},
{
"name": "PQRSTV",
"id": "789456"
},
{
"name": "LKJHMN",
"id": "456789"
}
],
"paging": {
"next": "https://graph.facebook.com/12343434/friends?access_token=CAAJVBDOfUeQBAadfASDFdfdkdERdfdg8pVgJCMbSwIkWyQ0tIjNwoPPIjni7JeMyMbkeTNmxsKRiUe3q0h74Ngl3Ylue2Oz0XlepxUgZBoASpkSted2WV414ziawNZAHW68vLgCArRyxC8vNPeVmoZAueqnL1COrdSvkSItkVXbYVbueUZAhyBwZDZD&limit=5000&offset=5000&__after_id=100006343431073"
}
}
Anyway to parse the JSON that I'm receiving to use that directly in Typeahead JS or any other way to implement it?
you must convert the name key to value ou tokens. Typeahead.js just recognizes to autocomplete what is written in these keys.
i had the same problem with Twitter API. it may be helpful: how to integrate typeahead.js with twitter api

Using Facebook request dialog with Meteor

I'm trying to send an "app" invite to user friends using the Facebook JavaScript SDK.
Here is a template event when click the Facebook button:
"click #fb": function (e, tmp) {
Meteor.loginWithFacebook({
requestPermissions: ['user_likes',
'friends_about_me',
'user_birthday',
'email',
'user_location',
'user_work_history',
'read_friendlists',
'friends_groups',
'user_groups']
}, function (err) {
if (err) {
console.log("error when login with facebook " + err);
} else {
FB.api('/' + Meteor.user().services.facebook.id + '/friends', { fields: 'name,picture' }, function (response) {
if (response && response.data) {
friends = response.data;
friends_dep.changed();
}
});
}
});
}
after that i want the user to invite people to my app, my code looks like this (another template event):
FB.ui({method: 'apprequests',
message: 'My Great Request'
}, function(response) {
if (response && response.post_id) {
alert('Post was published.');
} else {
alert('Post was not published.');
}
}
);
And it's working. There is a Facebook dialog with all the user friends, but when trying to send the message, I get the response error = 'Post was not published.'
What am I doing wrong here?
Basically the user can build a group - and I want the user to be able to invite his facebook friends into that group. Is there anyway that when sending the request the reciver will just press "yes" and will be automatically added to the sender group?
note I'm using my local machine aka localhost:3000
Can you try removing the && response.post_id portion from the if statement?
According to the Facebook API docs for the Requests Dialog: https://developers.facebook.com/docs/reference/dialogs/requests/ the response will just have 'request' and 'to' data. It looks like you've copy and pasted your callback from an example they give for the Posts Dialog. If you still get an error after removing this then you aren't getting a response, I am unsure how the JS SDK handles responses. If you can get other API calls to work using js sdk then I'm really not sure.
I recently worked with the Facebook API and opted not to use the JS SDK because it seemed to be at odds with using the accounts-facebook package. I'm curious if you're using that too.
Some Facebook API calls like creating a Post (and possibly this one) do require a dialog box, I'll outline how I got around this without using the JS SDK in case it helps you or anyone else. I would just form the URL client side and open a popup window e.g. here's how I handled sending a post:
'click .send-message': function() {
var recipient = this.facebook_id;
var config = Accounts.loginServiceConfiguration.findOne({service: 'facebook'});
var url = "http://www.facebook.com/dialog/feed?app_id=" + config.appId +
"&display=popup&to=" + recipient + "&redirect_uri=" + Meteor.absoluteUrl('_fb?close');
window.open(url, "Create Post", "height=240,width=450,left=100,top=100");
}
Then to get the response server side:
WebApp.connectHandlers
.use(connect.query())
.use(function(req, res, next) {
if(typeof(Fiber)=="undefined") Fiber = Npm.require('fibers');
Fiber(function() {
try {
var barePath = req.url.substring(0, req.url.indexOf('?'));
var splitPath = barePath.split('/');
if (splitPath[1] !== '_fb') {
return next();
}
if (req.query.post_id) {
//process it here
}
res.writeHead(200, {'Content-Type': 'text/html'});
var content = '<html><head><script>window.close()</script></head></html>';
res.end(content, 'utf-8');
} catch (err) {
}
}).run();
});
This code is very similar to the code used in the oauth packages when opening the login popup and listening out for responses.

Meteor re-render template after user login

Ok so im using Facebook API graph when the user is logging in using facebook
im getting the user friend list + friends pictures like that:
Template.user_loggedout.events({
"click #fb": function (e, tmp) {
Meteor.loginWithFacebook({
requestPermissions: ['user_likes',
'friends_about_me',
'user_birthday',
'email',
'user_location',
'user_work_history',
'read_friendlists',
'friends_groups',
'user_groups']
}, function (err) {
if (err) {
console.log("error when login with facebook " + err);
} else {
FB.api('/' + Meteor.user().services.facebook.id + '/friends', { fields: 'name,picture' }, function (response) {
if (response && response.data) {
friends = response.data
}
})
}
});
}
and as expected i get friends array inside there are objects(represented as friends).
at some point when the user clicks a link i want to show the user his friends list.
so i got this html:
Template.add_friends.helpers({
friends_list: friends
});
template name="add_friends">
<div class="friends_Page">
{{#each friends_list}}
<li>{{name}}</li>
{{/each}}
</div>
</template>
the problem is that the friends object gets updated after the app as started and when the user clicked the login button using facebook.
so how to re-render when i get the callback from facebook graph api?
i dont want to store the friends in database (its already available thanks to facebook )
The most natural way to force a redraw when data is changed is to use a dependency on that data.
var friends = [];
var friends_dep = new Deps.Dependency();
Template.myTemplate.friends_list = function() {
friends_dep.depend(); /* Causes the helper to rerun when data changes */
return friends;
};
...
function callback() {
...
friends = response.data;
friends_dep.changed(); /* Call this after you set the new data */
}

Categories

Resources