FB.api not working every time - javascript

I am new to Facebook Javascript SDK. I am trying to create an application using this API. But has hard luck while usign the FB.api method. Somehow my FB.api method is not working properly each time. Sometimes it will give the response (I am just accessing response.name) while other time it will not invoked properly.
window.fbAsyncInit = function() {
FB.init({
appId : 'my_app_id', // App ID
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
oauth : true, // enable OAuth 2.0
xfbml : true // parse XFBML
});
FB.getLoginStatus(function(response) {
if (response.authResponse) {
alert('user is:'+response.status);
userId = response.authResponse.userID;
FB.api('/me',function(response) {
alert('Inside FB.api function');
document.getElementById("userInfo").innerHTML = 'Welcome <img src="https://graph.facebook.com/'+ response.id + '/picture" style="margin-right:5px"/>' +response.name + '!';
});
}
});
};
Other methods FB.ui and FB.getLoginStatus and Facebook like button is working as expected, but only FB.api is not working seamless manner as others. Do not why? Please help me to idenify the problem.

I had the exact same problem. This answer pointed me into the right direction:
FB.api does not work when called right after FB.init
To solve my problem I had to subscribe to the correct event. In my case it was 'auth.authResponseChange' after FB.init
FB.Event.subscribe('auth.authResponseChange', function(){
FB.api('/me',function(r){
console.log(r.id);
if (!r || r.error) {
alert('Error occured');
} else {
alert(r.name);
}
});
});

That code works fine for me, but you might want to try renaming your response variables. Inside the FB.api callback, you actually have two response variables which will undoubtedly cause problems. Try changing them and see if you get different results.
FB.getLoginStatus(function(loginResponse) {
if (loginResponse.authResponse) {
alert('user is:'+loginResponse.status);
userId = loginResponse.authResponse.userID;
FB.api('/me',function(apiResponse) {
alert('Inside FB.api function');
document.getElementById("userInfo").innerHTML = 'Welcome <img src="https://graph.facebook.com/'+ apiResponse.id + '/picture" style="margin-right:5px"/>' +apiResponse.name + '!';
});
}
});
Its possible there is something else on your page affecting this. Do you have a link to your page?

I had the same problem. FB.api just stopped working silently at some point in my app. I noticed it was due to a DOM manipulation of :
<div id="fb-root"></div>
Either a duplication or anything. You should check that point. It looks like Johan Strydom's problem.

Related

Facebook Login via PHP SDK, then use JS SDK

I have developed an application where users login via facebook (PHP SDK); now I would like to add JS SDK too, because I want to implement a generic friend selector (http://facebook-friend-selector.codersgrave.com/) that works with JS SDK. I have two questions about:
1) Can mixing the two SDK lead to problems?
2) I added the JS SDK code as explained in the documentation and tried a simple request
FB.api('/me/friends', function(response) {
alert(JSON.stringify(response));
});
but I get an error (unknown error); I also tried a dialog box
FB.ui({
method: 'feed',
link: 'https://developers.facebook.com/docs/dialogs/',
caption: 'An example caption',
}, function(response){});
but the box appears and suddenly disappears. I think the issue is related to the authentication...I guess, since my users are authenticated via PHP, that I need to pass the access token to JS, but how? This question Passing the Facebook Authorization Token from PHP to Javascript seems to be exactly what I need but I don't understand the answer: it says to store the token in a cookie, but how can JS know about it, which name the cookie should have?
Finally, if I do something like
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
alert('connected');
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
}
});
I actually get a "connected" alert, that means that JS knows that the user is logged in, even if the login was via PHP, so where is the problem?
Solved. My code contained two stupid mistakes, this is the correct code:
function test(){
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
FB.api('/me/friends', function(response) {
alert(JSON.stringify(response));
});
}
});
}
Test
In the first version the call to the friends method was outside the getLoginStatus method, so it was called before setting the variable accesToken, furthermore, I haven't the "return false" statement after the test() call.

FB.getLoginStatus doesn't work in Chrome even sandbox disable

I follow railscast to add "sign in with Facebook" feature in my site, there is no problem to login. But when try to logout, it seems that FB.getLoginStatus never got fire even when I disable Sandbox Mode in facebook developer app settings (as suggested in some other discussion):
(function() {
jQuery(function() {
$('body').prepend('<div id="fb-root"></div>');
return $.ajax({
url: "" + window.location.protocol + "//connect.facebook.net/en_US/all.js",
dataType: 'script',
cache: true
});
});
window.fbAsyncInit = function() {
FB.init({
appId: 'xxxxxomittedxxxxx',
cookie: true,
status: true,
xfbml: true,
oauth: true
});
$('#sign_in').click(function(e) {
e.preventDefault();
return FB.login(function(response) {
if (response.authResponse) {
return window.location = '/auth/facebook/callback';
}
});
});
return $('#sign_out').click(function(e) {
FB.getLoginStatus(function(response) {
if (response.authResponse) {
return FB.logout(response.authResponse);
}
});
return true;
});
};
}).call(this);
The reason I know the FB.getLoginStatus never get in (or doesn't work) is I replace the body with:
FB.getLoginStatus(function(response) {
return alert("I am here!");
});
and I cannot see my alert while "sign_out" click.
I am running both Chrome and Firefox having the same behaviour. Could anybody help to spot what am I missing? Thanks a lot.
Let me describe more specific about the "behaviour" I encountered:
sign in with Facebook from mysite.com the first time a Facebook login window will popup and ask for email and password, and I can sign in to my site perfectly ok and work as expected
then I click on sign_out button from mysite.com/users/1, it looks like it sign out ok.
then sign in with Facebook from mysite.com again, now it won't popup the Facebook login window anymore and login to mysite.com/users/1 directly without asking email and password!
if I open another browser window and go to facebook.com and logout from there, then when I sign in with Facebook from mysite.com, it will popup a Facebook login window now and ask for my email and password.
I would like my site to behave: "when logout from mysite.com/users/n and sign in with Facebook again from mysite.com, the Facebook login window shall popup"
Anyone could be of help? Thanks a lot.
EDIT:
Further investigation found the "root" cause might be still: the sign out is under the different route (or page) of the sign in route and FB.getLoginStatus just cannot be fire under the mysite.com/signout. The error message from firebug indicates that "Given URL is not allowed by the Application configuration.: One or more of the given URLs is not allowed by the App's settings. It must match the Website URL or Canvas URL, or the domain must be a subdomain of one of the App's domains."
To proof it is the route issue, I put a sign out link in the same route (page) as sign in route which is the root route mysite.com as specified in the "Website with Facebook Login", everything works and can logout as expected:
<%= link_to "sign out facebook", "#" , id: "sign_out" %>
by the way the sign_out js is revised to get rid of FB.logout(response.authResponse) uncaught [object Object] error, because FB.logout expects function as parameter:
return $('#sign_out').click(function(e) {
FB.getLoginStatus(function(response) {
if (response.authResponse) {
FB.logout();
}
}, true);
});
};
So, the bottom line: FB.getLoginStatus might still have a bug which cannot handle the call from a different route than sign in route. (I tested with Chrome, Firefox and Safari and all behave the same but not true for IE10. Somehow IE10 works even sign out at different route.)
Any comment from people who have similar problem? Please advise. Thank you very much in advance.
Try adding true as second parameter to getLoginStatus, as stated in FB dev doc:
FB.getLoginStatus(function(response) {
// this will be called when the roundtrip to Facebook has completed
}, true);
This should avoid caching.
Another option is to subscribe to events:
FB.Event.subscribe('auth.login', function(response) {
// do something with response
});
All from here
Comment if you have questions.
EDIT:
I modified your script a little bit, removed unneeded code parts. You had too many returns that are not needed. I tried sign out within this modified script, it works as you need it.
Events subscription is for check purposes.
<head>
<title>Exam entry</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
</head>
<body>
<div id="fb-root"></div>
<input type="button" value="Sign in" id="sign_in" />
<input type="button" value="Sign out" id="sign_out" />
<script type="text/javascript">
window.fbAsyncInit = function () {
FB.init({
appId: '586844044669652',
cookie: true,
status: true,
xfbml: true
});
// Here we subscribe to the auth.authResponseChange JavaScript event. This event is fired
// for any authentication related change, such as login, logout or session refresh. This means that
// whenever someone who was previously logged out tries to log in again, the correct case below
// will be handled.
FB.Event.subscribe('auth.authResponseChange', function (response) {
// Here we specify what we do with the response anytime this event occurs.
if (response.status === 'connected') {
// The response object is returned with a status field that lets the app know the current
// login status of the person. In this case, we're handling the situation where they
// have logged in to the app.
testAPI();
} /*else if (response.status === 'not_authorized') {
// In this case, the person is logged into Facebook, but not into the app, so we call
// FB.login() to prompt them to do so.
// In real-life usage, you wouldn't want to immediately prompt someone to login
// like this, for two reasons:
// (1) JavaScript created popup windows are blocked by most browsers unless they
// result from direct interaction from people using the app (such as a mouse click)
// (2) it is a bad experience to be continually prompted to login upon page load.
FB.login();
} else {
// In this case, the person is not logged into Facebook, so we call the login()
// function to prompt them to do so. Note that at this stage there is no indication
// of whether they are logged into the app. If they aren't then they'll see the Login
// dialog right after they log in to Facebook.
// The same caveats as above apply to the FB.login() call here.
FB.login();
}*/
});
$('#sign_in').click(function (e) {
e.preventDefault();
FB.login(function (response) {
if (response.authResponse) {
//return window.location = '/auth/facebook/callback';
}
});
});
$('#sign_out').click(function (e) {
FB.logout(function (response) {
console.log("Here logout response", response);
});
});
};
// Here we run a very simple test of the Graph API after login is successful.
// This testAPI() function is only called in those cases.
function testAPI() {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function (response) {
console.log('Good to see you, ' + response.name + '.');
});
}
// Load the SDK asynchronously
(function (d) {
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) { return; }
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
</script>
</body>

Facebook js sdk can't retrieve name of logged user

I am using the facebook JS SDK. I am currently logged in facebook and my code is the folowing :
$(document).ready(function() {
FB.init({
appId: "myappID",
xfbml: true
});
FB.api('/me', function(response) {
alert(response.name);
});
});
The alert I'm getting says "undefined". Why ? Is there a way to get the Facebook unique app-id ?
Thank you very much
The alert I'm getting says "undefined". Why ?
Most likely because your user account hasen’t connected to your app yet.
Call FB.login first, and put the API call into the callback handler.
Because you haven't authorized your app yet.
Use FB.login to login to your app first.
I found weird that you are initializing the FB JS SDK inside a jQuery's $(document).ready.
Are you doing sync-loading? If you are following the Facebook's instructions you are actually doing a async-loading, which is better, because does not block the page loading. In a async-load, the <script> tag that contains all.js (the Facebook's JS SDK) is attached to document DOM after the $(document).ready event triggers.
So, you are trying to access a js-object (FB) that is not defined yet. It is better to assign your code to the window.fbAsyncInit, as instructed in Facebook's documentation:
window.fbAsyncInit = function() {
FB.init({
appId: 'AppID',
cookie: true, // I think you'll need this cookie to make the API call
xfbml: true
});
// Additional initialization code here
FB.api('/me', function(response) {
alert(response.name);
});
};
Good luck!

FB.logout() called without an access token

I'm trying to log out of a website i've created with Facebook integrated.
Logging in works fine, but when I want to log out Firebug consistently gives me this error:
FB.logout() called without an access token.
I'm using the Facebook JavaScript SDK, and the code I've got to logout looks like this:
$(document).ready($(function () {
$("#fblogout").click(facebooklogout);
}));
function facebooklogout() {
FB.logout(function (response) {
}
)};
This is the logout code specified at the Facebook Developers Documentation just with a button being assigned the method on document.ready
Before this code I have the FB.init() method, that all runs fine.
If anyone's got a solution as to why FB.logout doesn't have an access token, it'd be appreciated.
To logout from the application which uses facebook graph API, use this JavaScript on the logout page just after the <form> tag:
window.onload=function()
{
// initialize the library with your Facebook API key
FB.init({ apiKey: 'b65c1efa72f570xxxxxxxxxxxxxxxxx' });
//Fetch the status so that we can log out.
//You must have the login status before you can logout,
//and if you authenticated via oAuth (server side), this is necessary.
//If you logged in via the JavaScript SDK, you can simply call FB.logout()
//once the login status is fetched, call handleSessionResponse
FB.getLoginStatus(handleSessionResponse);
}
//handle a session response from any of the auth related calls
function handleSessionResponse(response) {
//if we dont have a session (which means the user has been logged out, redirect the user)
if (!response.session) {
window.location = "/mysite/Login.aspx";
return;
}
//if we do have a non-null response.session, call FB.logout(),
//the JS method will log the user out of Facebook and remove any authorization cookies
FB.logout(handleSessionResponse);
}
The code works and is live on my site.
I went for the less trivial solution:
function facebookLogout(){
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
FB.logout(function(response) {
// this part just clears the $_SESSION var
// replace with your own code
$.post("/logout").done(function() {
$('#status').html('<p>Logged out.</p>');
});
});
}
});
}
Figured it out after so many tries.
Generally response.authResponse.accessToken contains token. So, its error about the accessToken not being there.
Think logically, where does that response come from in your code? Out of nowhere.
So, we need to get that response object from a function and get this working.
I don't know how it worked for others, but this worked for me.
Just replace the code with this
function logout(){
FB.getLoginStatus(function(response) {
FB.logout(function(response){
console.log("Logged Out!");
window.location = "/";
});
});
}
What we do here is, get the login status if the user is logged in and get the corresponding response in return, which contains all the necessary tokens and data. Once this is fetched, the token is used to log out the user.
I've tried something like this:
function fbLogout(){
if(typeof FB.logout == 'function'){
if (FB.getAuthResponse()) {
FB.logout(function(response) { window.location.href = PROJECT_PATH + '/index/logout'; });
return;
}
};
window.location.href = PROJECT_PATH + '/index/logout';
return;
}
Should be something more like this. There was a change to the JS API where you have to use authResponse instead of just session.
//handle a session response from any of the auth related calls
function handleSessionResponse(response) {
//if we dont have a session (which means the user has been logged out, redirect the user)
if (!response.authResponse) {
return;
}
//if we do have a non-null response.session, call FB.logout(),
//the JS method will log the user out of Facebook and remove any authorization cookies
FB.logout(response.authResponse);
}
The error says that you don't have an access token, you have to check for one using the FB.getAccessToken() function.
If there is no access token the function returns null. See example below:
function facebooklogout() {
try {
if (FB.getAccessToken() != null) {
FB.logout(function(response) {
// user is now logged out from facebook do your post request or just redirect
window.location.replace(href);
});
} else {
// user is not logged in with facebook, maybe with something else
window.location.replace(href);
}
} catch (err) {
// any errors just logout
window.location.replace(href);
}
}
With Typescript this function do work fine ..
signOutFacebook(): void {
/*SIGN OUT USER FACEBOOK.*/
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
FB.logout(function (response) {
console.log("Logged Out!");
});
} else {
console.log("The person is not logged into your webpage or we are unable to tell. !");
}
});
}/*FINAL 'signOutFacebook()'. */

FB.INIT not forcing login even with status:true js sdk

My app allows users to send requests using Facebook Requests Dialogue.
I run the init as follow:
<div id="fb-root"></div>
<script src="http://connect.facebook.net/en_US/all.js"></script>
<script>
FB.init({
appId: '193078857407882',
status: true,
cookie: true,
xfbml: false,
});
</script>
From what I understand in the documentation the 'status: true' is supposed to check if the user is logged in to facebook.
However in my app when the user is not logged in it just shows the following error message:
An error occurred with hbg. Please try again later.
How can I force the application to check if the user is logged in and if not to log in?
Rails 3.0.7, Ruby 1.9.2, Js SDK
According to the Facebook docs for FB.getLoginStatus, if you want to receive the response from passing status: true to FB.init, then you need to subscribe to the auth.statusChange event:
While you can call FB.getLoginStatus any time (for example, when the
user tries to take a social action), most social apps need to know the
user's status as soon as possible after the page loads. In this case,
rather than calling FB.getLoginStatus explicitly, its possible to
check the user's status by setting the status: true parameter with you
call FB.init.
To receive the response of this call, you must subscribe to the
auth.statusChange event. The response object passed by this event is
identical to that which would be returned by calling FB.getLoginStatus
explicitly.
So in your code you would do something like
FB.Event.subscribe('auth.authResponseChange', function(response) {
alert('The status of the session is: ' + response.status);
});
Except you would subscribe to auth.statusChange instead. Note, however, that according to the FB.Event.subscribe docs:
auth.statusChange() does not have a 'status' field.
You can check login status by calling FB.getLoginStatus
FB.getLoginStatus(function(response) {
if (response.authResponse) {
// logged in and connected user
} else {
FB.login(function(res) {
if (res.authResponse) {
// user logged in
} else {
// user cancelled login
}
});
}
});

Categories