After a rather frustrating bout with Facebook OAuth 2, and having my Facebook Connect login break completely on my site (www.thegameeffect.com), I'm turning to the wise minds of StackOverflow in hope of some guidance.
Things were working rather nicely as of a 1-2 months ago, but recently I've been having problems. Basically, I have followed the steps according to the FB developers site, and hit several other help guides from here, such as this link: (http://stackoverflow.com/questions/8537007/facebook-cookie-and-oauth-2-0-changes) and have sadly not had any luck.
My FB.Init code looks like below:
<div id="fb-root"></div>
<script type="text/javascript">
window.fbAsyncInit = function () {
FB.init({ appId: '145290112183820', status: true, cookie: true, xfbml: true, channelUrl: 'http://www.thegameeffect.com/fbchannel.html' });
//, oauth:true
};
(function () {
// var js, id = 'facebook-jssdk'; if (d.getElementById(id)) { return; }
// js = d.createElement('script'); js.id = id; js.async = true;
// js.src = "//connect.facebook.net/en_US/all.js";
// d.getElementsByTagName('head')[0].appendChild(js);
var e = document.createElement('script'); e.async = true;
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js#xfbml=1';
document.getElementById('fb-root').appendChild(e);
} ());
</script>
I have tried all variations of this, with oauth:true included, the channelurl excluded, the self invoking function with the top part uncommented, and still all that happens when I try to log in is the auth window pops up briefly, and then disappears. The code that gets executed when you click on the FB icon in the top left of the header is below:
FB.login(function (response) {
if (response.session) {
// do server side work (this never gets hit)
}
});
Any suggestions?
Some minor changes will make your code work :
window.fbAsyncInit = function () {
FB.init({ appId: '145290112183820', status: true, cookie: true,
xfbml: true, channelUrl:
'http://www.thegameeffect.com/fbchannel.html', oauth: true });
};
and
FB.login(function (response) {
if (response.authResponse) {
}
});
So, after a bit more digging, and a lot of debugging, I finally found the solution. I was able to get the javascript side of things working thanks to manishekhawat, and the server side thanks to this awesome post:
http://amirrajan.net/Blog/facebook-oauth-authentication-and-iframe-apps
For anyone having problems with the new Facebook oAuth cookie in ASP.NET, this is an amazing tutorial!
Thanks again for the help today; I'm glad to finally have everything in working order.
Change,
FB.getLoginStatus(function(response) {
if (response.session) { ........................
}
by
FB.getLoginStatus(function(response) {
if (response.authResponse) {
........................
}
My facebook app make Infinite loop in sdk 3.1.1
Related
I am trying to use the Facebook PHP and JS SDKs together in order to create a web app that will double as a canvas app. In the current setup I am experiencing issues when the page is left or a while and the system reverts back to the login screen. It is important to not I am using a dynamic domain mapper and there are a few possible URLs /dev/, /dev/pool/, /dev/pool/edit/, etc. that the user might visit and experience the app.
I read around and found that authorizing with the JS SDK is the correct method (I could be wrong?) and then using the PHP SDK to sort through everything else will work just find, gaining the access token naturally.
I know this is something wrong with my authentication setup, as I see it reload sometimes, I also get stuck with a login button that doesn't do anything if I am on a sub page, and if I don't touch the site for a couple of minutes the system tries to re-auth for no reason.
Any ideas as to what I am doing wrong?
Thanks!
Here is the JS set up on my site:
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId: 'XXXXX',
channelUrl: 'http://www.domain.com/channel.php',
status: true,
cookie: true,
xfbml: true,
oauth: true,
});
FB.Event.subscribe('auth.login', function(response) {
alert('refreshing')
window.location.reload();
});
FB.Event.subscribe('auth.logout', function(response) {
window.location.reload();
});
FB.Canvas.setSize({ width: 810 });
FB.Canvas.setAutoGrow();
};
(function(d, debug){
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" + (debug ? "/debug" : "") + ".js";
ref.parentNode.insertBefore(js, ref);
}(document, /*debug*/ true));
</script>
Here is the PHP flow of calling the Facebook Object
$fb = new FbDoa();
if ($fb->isAuthed() === false) {
echo $fb->getLoginButton();
}
else {
echo $fb->getProfileInfo();
}
Here is the PHP contents of the FbDoa Object ($fb):
public function __construct() {
require_once(Facebook/facebook.php');
$this->facebook = new Facebook(array(
'appId' => 'XXXXX',
'secret' => 'XXXXXXXXXX',
'cookie' => true,
));
$this->user = $this->facebook->getUser();
if ($this->user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$this->user_profile = $this->facebook->api('/me');
} catch (FacebookApiException $e) {
//echo '<pre>'.htmlspecialchars(print_r($e, true)).'</pre>';
$this->user = null;
}
}
}
public function isAuthed() {
if ($this->user) {
return true;
}
else {
return false;
}
}
public function getLoginButton() {
$scope = 'email,user_likes,friends_likes,publish_actions,publish_stream,read_friendlists';
return '<fb:login-button size="xlarge" perms="'.$scope.'"></fb:login-button>';
}
public function getProfileInfo() {
return $this->user_profile;
}
UPDATE 1:
It really seems like window.location.reload(); is not doing anything, if I hit the login button over and over nothing happens, but I refresh it works. That being true the app's auth should last longer than a couple mins, which means there are a few issues before me. Any ideas?
UPDATE 2:
The issue could be with my server-side code? anyone know anything about PHP+JS SDK?
The signed request is saved in a cookie similar to fbsr_appid. From that you can use the code to deal with it. Here is how your flow should look
As long as there is a base url in your app settings it should redirect to all.
I have followed the Facebook documentation to put a Login button on a page. Everything was working fine until recently. Without any code change on my part the button now exhibits a strange behavior:
(problem #1) if I am already logged into Facebook (have facebook auth cookie) then when I visit my site the button just shows "Log In" even though I have specified a custom tag. It should show "Login with Facebook".
(problem #2) If I am not logged into Facebook, then when I visit my site the fb login button is not there at all.
Here is the code that I have:
I have included xmlns:fb="http://ogp.me/ns/fb#" and xmlns:og="http://ogp.me/ns#" as attributes to my main html node.
Then I have:
<div class="fb-login-container">
<fb:login-button scope="email" size="medium" onlogin="CheckFBAccount();">Login with Facebook</fb:login-button>
</div>
<script type="text/javascript" src="//connect.facebook.net/en_US/all.js"></script>
<script type="text/javascript" language="javascript">
$(window).load(function ()
{
window.FB.init({ appId: XXXXXXXXXXX, status: true, cookie: true, xfbml: true, oauth: true });
});
</script>
Please note that here I am loading the FB API synchronously. I have tried replacing the above script code with an asynchrounous call like this:
window.fbAsyncInit = function ()
{
FB.init({
appId: XXXXXXXXXXXX,
status: true,
cookie: true,
xfbml: true
});
};
(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));
This fixes the problem of button not showing up at all (problem #2 solved) but if I already have FB auth cookie on the system then it still ignores my custom label (problem #1 still there).
I am going through the forums and documentation trying to figure out what changed but have not found anything yet. Clearly FB changed something again (or perhaps it's a bug that they introduced). Any help would be much appreciated.
NOTE: As long as the button is visible on the page (with of without my custom label) the click and authentication behavior is fine. Again the problem is the button not showing up at all or ignoring my custom label.
I think you'll need to load the FB libraries asynchronously and roll your own custom FB login button.
Here's some code I modified from a German website - http://daily.siebler.eu/2011/04/facebook-like-button-asynchronous-loading-with-jquery/
If you're already loading jQuery, this is a cleaner solution that lets you keep your initialization code inside of $(window).load
<div id="fb-root"></div>
<script type="text/javascript">
$(window).load(function ()
{
// Save the cache so we can restore it later
var cache = jQuery.ajaxSettings.cache;
jQuery.ajaxSettings.cache = true;
// Load FB library asynchronously
// 'en_US' is hard coded, but you could render out a variable
// that contains the correct FB locale code for localized pages
jQuery.getScript('//connect.facebook.net/en_US/all.js', function ()
{
window.FB.init({ appId: XXXXXXXXXXX, status: true, cookie: true, xfbml: true, oauth: true });
// Wire up any additional FB events; for example, here's how
// to listen for FB "Like" events
window.FB.Event.subscribe("edge.create", function (response)
{
// Do something interesting
});
});
// Restore the jQuery cache
jQuery.ajaxSettings.cache = cache;
// Wire up the click event for your custom FB login button
$("#idFacebookLoginBtn").on("click", function (e)
{
e.preventDefault();
window.FB.login(function () { CheckFBAccount(); }, { scope: 'email' });
return false;
});
});
</script>
Next, you'd need to make your own button, maybe like this:
<div id="idFacebookLoginBtn" class="facebook-login-btn" >Login with Facebook</div>
I'm developing an app for a Facebook page with the 'timeline' layout, and I want the height of the app to scale with the content, but the height of the app is fixed at 800px.
The current app settings show that the height is set to 'fluid,' but I have also tried fixing the height to random values and witnessed no change.
How to I get the height of my app to scale to it's content? Thanks for any responses.
Update:
So appending this to my body tag worked.
<body onload="FB.Canvas.setSize({width: 810, height: 910})">
<div id="fb-root"></div>
<script>
(function () {
var e = document.createElement('script');
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js#xfbml=1&appId=YOURAPPID;
e.async = true;
document.getElementById('fb-root').appendChild(e);
} ());
</script>
But I have zero idea why it worked, so I guess I'll change my question to 'what does the above code do?' so I can actually understand what steps to take next time. I'll put this as an answer for now to close off the question though.
This is the proper way to set things up, I just had to stare at it for a while and read the documentation way too many times. Putting the following below the fb-root div worked like a champ.
window.fbAsyncInit = function () {
FB.init({
appId: 'YOURAPPID', // App ID
channelUrl: '/channel.html', // Channel File
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
xfbml: true // parse XFBML
});
FB.Canvas.setAutoGrow(); //Resizes the iframe to fit content
};
// 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));
Embed javascript code to increase height of iframe
<script type="text/javascript">
window.fbAsyncInit = function() {
FB.Canvas.setAutoResize( 100 );
}
function sizeChangeCallback() {
FB.Canvas.setSize({ width: 810, height:1300 });
}
</script>
<div id="fb-root"></div>
<script src="http://connect.facebook.net/en_US/all.js"></script>
<script>
FB.init({
appId : 'YOUR APP ID',
status : true,
cookie : true,
xfbml : true
});
</script>
The response by Ashish worked well for me.
I also included a body style to prevent the scrollbars from appearing for a second while the page loads:
body {overflow:hidden;}
I am developing a facebook (iframe) app.
I have included following code at bottom of my page:
<script>
window.fbAsyncInit = function() {
FB.Canvas.setAutoResize();
FB.init({
appId : '<?php echo FACEBOOK_APP_ID; ?>',
session : '<?php echo json_encode($session); ?>',
status : true,
cookie : true,
xfbml : true
});
// whenever the user logs in / out, we refresh the page
FB.Event.subscribe('auth.login', function() {
window.location.reload();
});
FB.Event.subscribe('auth.logout', function() {
window.location.reload();
});
};
(function() {
var e = document.createElement('script');
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
e.async = true;
document.getElementById('fb-root').appendChild(e);
}());
</script>
The problem here is, it seems that auth.login and auth.logout events are getting fired immediately inside window.fbAsyncInit function, even if I do not log-out from (or log-in to if logged out) my facebook profile.
I am doing no such action, even then these events seem to get fired, which causes their handler functions to reload my app (window.location.reload();), and the app goes into infinite reload loop.
Please guide me.
Thanks
From my experience instead of using auth.logout and auth.login events you may try the following code:
FB.Event.subscribe('auth.authResponseChange', function(response) {
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
// the user is logged in and connected to your
// app, and response.authResponse supplies
// the user's ID, a valid access token, a signed
// request, and the time the access token
// and signed request each expire
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
} else if (response.status === 'not_authorized') {
// the user is logged in to Facebook,
//but not connected to the app
} else {
// the user isn't even logged in to Facebook.
}
});
});
I've been stuck trying to solve this bug for a few days. The thing is that auth.login event is fired when the SDK is loaded even if you're already connected thus creating an infinite loop. I've solved it when i made the code listen to the authlogin event and reloading the page only if the user is not connected.
<script type="text/javascript">
window.fbAsyncInit = function() {
FB.init({
appId : '<?php echo AppInfo::appID(); ?>', // App ID
channelUrl : '//<?php echo $_SERVER["HTTP_HOST"]; ?>/channel.html', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// Listen to the auth.login which will be called when the user logs in
// using the Login button
FB.getLoginStatus(function(response) {
console.log (response.status);
//this is useful if you want to avoid the infinite loop bug
//it only reloads page when you log in
if (response.status != 'connected') {
FB.Event.subscribe('auth.login', function(response) {
// We want to reload the page now so PHP can read the cookie that the
// Javascript SDK sat. But we don't want to use
// window.location.reload() because if this is in a canvas there was a
// post made to this page and a reload will trigger a message to the
// user asking if they want to send data again.
//window.location = window.location;
//Im using the window.location.reload()
window.location.reload();
});
}
});
FB.Canvas.setAutoGrow();
};
// Load the SDK Asynchronously
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
Hope this works!
Anyway this is not the only problem i have. please check this post and help me if you can
impossible to read $_SESSION vars on PHP facebook app
I've developed a simple website using facebook connect, and it has been working fine for the last month or so. Underneath the fb:login-button code is a fb:facepile. It has worked as expected until today, when instead of showing friend's pictures it displays the facebook homepage. Here is a screenshot of the problem http://i.stack.imgur.com/nZsbq.png
Here is the relevant code. It worked at one time, so I'm really confused what happened to cause this weird error. Any help would be greatly appreciated.
<div id="fb-root"></div>
<script type="text/javascript">
window.fbAsyncInit = function() {
FB.init({appId: '<?php echo $appkey; ?>', status: true, cookie: true, xfbml: true});
/* All the events registered */
FB.Event.subscribe('auth.login', function(response) {
// do something with response
login();
});
FB.Event.subscribe('auth.logout', function(response) {
// do something with response
logout();
});
};
(function() {
var e = document.createElement('script');
e.type = 'text/javascript';
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
e.async = true;
document.getElementById('fb-root').appendChild(e);
}());
function login(){
document.location.href = "<?php echo $base_url.'/facebook/'; ?>";
}
function logout(){
document.location.href = "<?php echo $base_url.'/logout/'; ?>";
}
</script>
I cannot copy the two XFBML tags that follow the javascript. They are fb:login-button and fb:facepile
It is a reported bug but it seems that nobody at Facebook care about it. Very strange and disapointing for such big web company.
http://forum.developers.facebook.net/viewtopic.php?id=90734
You can report this bug by upvoting at the follwoing webpage :
http://bugs.developers.facebook.net/show_bug.cgi?id=15490
It looks like <fb:facepile></fb:facepile> is finally working again. The bug was marked as resolved on the Facebook bugtracker and is currently working as expected on my development server.