I am working on a website and wanted to give my users an option to log-in using facebook.
I am successful at logging in but events are not working for me.
Whenever i logged in, the function "login" was not called.....I have tried assigning this login function to other button for checking it manually, the alert worked but it didnt get any response.
Here my Code:
<div id="fb-root"></div>
<script type="text/javascript">
window.fbAsyncInit = function() {
FB.init({appId: MY_APP_ID, status: true, cookie: true, xfbml: true});
FB.Event.subscribe('auth.login', function(response) {
login();
});
};
function login(){
FB.api('/me', function(response) {
alert('You have successfully logged in, '+response.name+"!");
});
}
(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);
}()); </script>
<fb:login-button autologoutlink='true'
perms='email,user_birthday,status_update,publish_stream'></fb:login-button>
This is the facebook application setting:
Have you tried loading the all.js script in the <head> instead of #fb-root? Use the following:
(function(d){
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/es_LA/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
instead of:
(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);
}());
[EDIT: updated sample]
The SDK inserts elements into fb-root which expect to be positioned relative
to the body or relative to an element close to the top of the page.
Which might replacing the SDK source as well.
resource: Facebook Javascript SDK.
--
can you try to subscribe to other event and see if its work
FB.Event.subscribe('auth.statusChange', function(response) {
// do something with response
});
From Facebook documentation (try subscribing this instead)
auth.authResponseChange
This event is fired for any auth related change as they all affect the session: login, logout, session refresh. Sessions are refreshed over time as long as the user is active with your app.
auth.statusChange
Typically you will want to use the auth.authResponseChange event. But in rare cases, you want to distinguish between these three states:
1. Connected
2. Logged into Facebook but not connected with your application
3. Not logged into Facebook at all.
Scenario 1 (New User)
Facebook Login Button's Text: "Login"
User State: User not connected
Now user clicks on login and completes the login flow.
Button's text changes to "Log Out" and this is the only time when'auth.login' triggers.
FB.Event.subscribe('auth.login', function (response) {
// do something with response
if (response.status === 'connected') {
// user connected
FB.api('/me', function (response) {
alert(response.name + " " + response.id);
});
}
});
Scenario 2 (Existing User)
If a user who is logged in to Facebook and has already authorized your app visits your app then the user automatically get's connected and Login Button's text is "Log Out".
In this case add the following code into the fbAsyncInit function:
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
// connected
alert(response.name + " " + response.id);
}
});
FB.getLoginStatus is called everytime the page refreshes but you can also call it anytime in your app by embedding it into a javascript function.
Related
Per documentation, the html attribute 'onlogin' can be used to run a callback function after a login is complete
However we're consistently getting the supplied function run twice, causing problems when it does actual work.
While we can catch this with a counter of how many times its run I'd rather have an understanding of why this happens and fix it than apply a workaround. The entirety of the code is below (won't run in snippet):
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>facebook login test</title>
<script src="/Vendors/jQuery/jquery-3.2.1.min.js"></script>
</head>
<body>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'foobar123456', // see https://developers.facebook.com/apps/
cookie : true,
xfbml : true,
version : 'v2.11' // see https://developers.facebook.com/docs/javascript/quickstart
});
FB.AppEvents.logPageView();
};
(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 = "https://connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
<!-- LOGIN BUTTON scope at: https://developers.facebook.com/docs/facebook-login/permissions/ -->
<div class="fb-login-button" data-width="250" data-max-rows="1" data-size="large" onlogin="fbLoginHandler" data-scope="public_profile,email" data-button-type="login_with" data-show-faces="false" data-auto-logout-link="true" data-use-continue-as="true"></div>
<script>
console.log("reached script tag");
var timesfbLoginHandlerFired = 0;
var fbLoginHandler = ()=>{
timesfbLoginHandlerFired++;
console.log("fbLoginHandler fired ["+timesfbLoginHandlerFired+"] times");
};
</script>
</body>
</html>
And the console:
Navigated to https://fbtest.dev/fblogin <- on page load
reached script tag <- on page load
XHR finished loading: POST "https://www.facebook.com/ajax/bz". <- on page load
XHR finished loading: POST "https://www.facebook.com/ajax/bz". <- on facebook login prompt window opening
fbLoginHandler fired [1] times <- on login complete
fbLoginHandler fired [2] times <- on login complete
My Faster workaround was as following:
I just set a variable called fblogin_done
fblogin_done = 0;
And in the function that is being executed twice i put a counter and a blocker with a timer
function CheckLoginState() {
if (fblogin_done == 1) return; // avoid twice executions
fblogin_done = 1;
window.setTimeout(function(){
fblogin_done = 0; // wait 1 second after a second execution
}, 1000);
}
A second was enough to me to avoid more than 1 execution,
It seems to have to do with the data-auto-logout-link set to true.
Setting that to false, stops the button from firing the onlogin function twice.
Without seeing how the SDK handles it, my best guess is that when the button changes to become a logout button, it must be checking for login and triggering the onlogin function a second time.
I found this to be a clean way of handling the double call.
function mainLogin() {
FB.getLoginStatus(function (response) { // when connected, login, avoids double call
if (response.status === 'connected') {
fbLogin();
};
});
}
function fbLogin() {
FB.api('/me?fields=name,id,email', function (response) {
if (!jQuery.isEmptyObject(response)) { //make certain we got a response object
console.log(response);
//todo: Get the FB data and process it...
} else {
//todo: err handling
}
});
}
When a user comes to our site, if they've logged into our Facebook app, we want to show them the "logged-in" view for the app showFacebook(). Otherwise, we want to display an option to login to the app or login to our site with a local account showLogin().
window.fbAsyncInit = function() {
FB.init({
appId : <cfif cgi.SERVER_NAME CONTAINS "dev">'460582120708297'<cfelse>'1422691834609812'</cfif>,
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
FB.Event.subscribe('auth.authResponseChange', function(response) {
// Handle the results of logging in
if (response.status === 'connected') {
showFacebook();
}
else {
showLogin();
}
});
// Check if the user is already logged into the Facebook app
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
showFacebook();
} else {
showLogin();
}
});
};
// 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));
This works great most of the time. But, sometimes, neither showFacebook() nor showLogin() are firing. My guess is that these are users who are at work or at school, and their network admins have blocked Facebook.
How can I detect that the Facebook JS file (http://connect.facebook.net/en_US/all.js) is not loading?
Check if window.FB is defined. If not, the library didn't load.
if (window.FB) {
// go for it
}
I went with a variation on Doge's response:
$(document).ready(function(e) {
// Show the login without the Facebook button if Facebook doesn't load in 5 seconds
setTimeout(function(){
if(!window.FB){
$("#facebook_login_area").hide();
showLogin();
}
},5000);
});
I give the asynchronous call from Facebook 5 seconds to load. If it hasn't loaded in that time, I display my showLogin() without the option to login to the Facebook app.
This problem had just showed up in my app when I view it on the native Android browser in ICS and Jellybean. All works as intended on desktop browsers and even Chrom for Android. This has occurred in the past few days, was working fine last week, and nothing in the code has changed.
The following code, which is a simplified version of what my app does, is essentially what I'm doing to initiate a connection to FB. I'm expecting the alerts in A and B, or A and C will pop, but instead, nothing happens.
window.fbAsyncInit = function () {
FB.init({
appId: '', // App ID
channelUrl: 'http://localhost/fb/channel', // Channel File
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
xfbml: true // parse XFBML
});
FB.getLoginStatus(function (response) {
alert("any response"); //<-- A
if (response.status == 'connected') {
alert("connected"); // <-- B
} else {
//somehow user was not already signed in or did not fully authorize
FB.login(function (response) {
if (response.authResponse) {
alert("connected"); // <-- C
} else {
console.log('User cancelled login or did not fully authorize.');
}
});
}
});
};
// 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));
Anyone experiencing that same and have a workaround or solution?
When I click on my FB log in button the FB auth dialog pops up. After I enter my FB credentials the dialog redirects to a url like this:
https://www.facebook.com/dialog/permissions.request?wholeBunchOfQueryParameters
or, if I was already logged into FB, the popup dialog is:
https://www.facebook.com/dialog/oauth?wholeBunchOfQueryParameters
but those are blank dialogs that stay open. Once I close the dialog the callback happens but not until then. This is the behavior on IE and Chrome.
I did have this working fine and I think it stopped working when I got a new computer so maybe it is environmental. I thought it has worked since then but maybe not. I reverted to a version of my code that was working and it no longer works either so that further suggests that it is environmental but I don't know what it could be. I could be off in the weeds.
Also, one other bit of info, I'm developing locally so I'm using localhost:port. I did a ton of research on this issue and did see someone say to use 127.0.0.1 instead of localhost so I did try that as well but it didn't make a difference.
Any idea why the dialogs won't close?
<fb:login-button perms="email,user_checkins" onlogin="afterFacebookConnect();"
autologoutlink="false" ></fb:login-button>
<div id="fb-root" style="display:inline; margin-left:20px;"></div>
<script language="javascript" type="text/javascript">
window.fbAsyncInit = function () {
FB.init({ appId: 'myAppId',
status: true, cookie: false, xfbml: true
});
};
function afterFacebookConnect() {
FB.getLoginStatus(function (response) {
alert("Hi");
var access_token = FB.getAuthResponse()['accessToken'];
if (response.authResponse) {
window.location = "../Account/FacebookLogin?token=" +
access_token;
} else {
alert(FB.getAuthResponse);
}
});
};
function logout() {
FB.getLoginStatus(function (response) {
var access_token = FB.getAuthResponse()['accessToken'];
if (response.authResponse) {
window.location = "../Account/Logout";
} else {
// user clicked Cancel
}
});
};
$(document).ready(function () {
if (document.getElementById('fb-root') != undefined) {
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);
}
});
</script>
This is a known bug that has surfaced in the last few days (see https://developers.facebook.com/bugs/241915819261223).
The good news is one of FB's Engineers has just stated the following, so we should see this resolved shortly:
We have a fix for this issue and it will be pushed soon. Stay tuned.
I have a Facebook Page Tab App that is not loading correctly until after the page is refreshed. I have been trying to solve this problem for over a week, and am reaching my wits end.
Here is the code:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="https:////connect.facebook.net/en_US/all.js"></script>
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '***************', // App ID
channelURL : '//www.********.com/**********/channel.html', // Channel File
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
});
// Additional initialization code here
};
// Load the SDK Asynchronously
(function(d){
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);
}(document));
</script>
<script type="text/javascript">
$(document).ready(function(){
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
//User Logged In
}
else if (response.status === 'not_authorized') {
//Log User Into App
}
else
{
top.location = "http://www.facebook.com";
}
});
});
</script>
Like I said, if add something like alert("Test") immediately after FB.getLoginStatus(function(response) { it doesn't pop up on the first page load, but does after the page is refreshed.
Can someone please help point me in the right direction?
Thanks,
Fred
First of all you are loading the SDK both Synchronously and Asynchronously. Remove the synchronous line. Then all your FB related lines should be within the window.fbAsyncInit. You can't subscribe to events before the sdk is fully loaded.
You can try it this way if you haven't already
FB.getLoginStatus(function(response) {
if (response.authResponse) {
// logged in and connected user, someone you know
} else {
// no user session available, someone you dont know
}
});