I'm trying to implement Facebook Connect login on my web page, and below you have my (poor) try so far.
If being logged out the login button is shown, as supposed.
If clicking the login button the Facebook login popup window appears, as supposed.
If loggin in the popup window disappears, the user gets logged in and the button changes to a logout button.
If clicking the logout button the user gets logged out, BUT!:
The button doesn't get changed to a login button.
Sometimes up to three popup windows (login) opens up.
The function testAPI() gets executed.
Sometimes the following error message is shown in the console: "Refused to display document because display forbidden by X-Frame-Options."
JS:
window.fbAsyncInit = function() {
FB.init({
appId : 'xxxxxxxxxxxxxxxx', // App ID
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) {
if (response.status === 'connected') {
showLogoutButton();
} else if (response.status === 'not_authorized') {
showLoginButton();
} else {
showLoginButton();
}
});
};
function showLoginButton() {
$('#FBButtonDiv').show();
$('#FBButton').html('Log in Facebook');
$('#FBButton').on('click', function(){
login();
});
}
function showLogoutButton() {
$('#FBButtonDiv').show();
$('#FBButton').html('Log out Facebook');
$('#FBButton').on('click', function(){
logout();
});
}
function login() {
FB.login(function(response) {
if (response.authResponse) {
// connected
testAPI();
showLogoutButton();
} else {
// cancelled
}
});
}
function logout() {
FB.logout(function(response) {
showLogoutButton();
});
}
function testAPI() {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + response.name + '.');
});
}
(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));
HTML:
...
<div id="FBButtonDiv"><button id="FBButton">Facebook login!</button></div>
...
CSS:
#FBButtonDiv {
display: none;
}
So, what can be wrong in my code?
Note: I know the code contains of alot of DRY but I'll do alot of refactoring when I get it to work.
Not particularly my speciality, JS/FB-API but I would guess:
function logout() {
FB.logout(function(response) {
showLogoutButton();
});
}
Should be:
function logout() {
FB.logout(function(response) {
showLoginButton();
});
}
Because after the response is recieved, the callback should be to show the login button to the now logged out user. Of course you should probably check the response similarly to login to confirm the logout was succesful.
Related
I've only started Javascript a few days ago, so this question might seem basic.
I've written some Javascript code to interact with the Facebook API.
The goal is to display all the pages managed by a user when he logs in via a Facebook login button.
The code seems to work as it does what it's supposed to do.
However, the console gives me the error "FB is not defined".
I've read all the other questions about this error and it seems to be linked to the asynchronous loading of the SDK, but i can't seem to figure this out.
How come i still get this error?
******EDIT 07/07/2017*******
Google Chrome's console gives me the "FB is not defined error" at the FB.getLoginStatus line of this portion of code:
function checkLoginStatus() {
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
getPagesList();
} else {
document.getElementById('pageslist').style.display = 'none'; //Hides the div when people are not connected
document.getElementById('pagestatistics').style.display = 'none'; //Hides the div when people are not connected
}
});
}
It also points to the following part, which seems to be the issue since, when i remove it from the code, the error disappears:
//Here below, _5h0o is the class of the logout button
//This checks the login status AFTER the user clicks on logout thanks to setTimeout
document.getElementsByClassName('_5h0o').onclick = setTimeout(function() {
checkLoginStatus();
}, 100);
Here is the full code:
//Initialize Facebook SDK + Check Login Status
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'xxxxxxxx',
xfbml : true,
version : 'v2.9'
});
checkLoginStatus();
};
(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/fr_FR/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
} (document, 'script', 'facebook-jssdk'));
</script>
//Facebook Login Button
<div class="fb-login-button" data-scope="public_profile, read_insights, pages_show_list" data-width="300" data-max-rows="1" data-size="large" data-button-type="login_with" data-show-faces="false" data-auto-logout-link="true" data-use-continue-as="false" onlogin="checkLoginStatusAfterLogin()" onclick="checkLoginStatus()"></div>
<script>
//Checks login status after people click on the Facebook button (useful for logout event)
function checkLoginStatus() {
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
getPagesList();
} else {
document.getElementById('pageslist').style.display = 'none'; //Hides the div when people are not connected
}
});
}
//Checks login status after people log in via the Facebook button
function checkLoginStatusAfterLogin() {
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
getPagesList();
document.getElementById('pageslist').style.display = 'inline-block';
} else {
checkLoginStatus();
}
});
}
//Here below, _5h0o is the class of the logout button
//This checks the login status AFTER the user clicks on logout thanks to setTimeout
document.getElementsByClassName('_5h0o').onclick = setTimeout(function() {
checkLoginStatus();
}, 100);
</script>
//Display the pages (in the form of clickable spans) for which the user has reading rights
<div id="pageslist"></div>
<script>
function getPagesList() {
FB.api('/me/accounts', {fields:'id, name'}, function(response){
document.getElementById('pageslist').innerHTML = ''; //Makes sure the div is cleared before populating it with the list of pages
for (i=0; i<response.data.length; i++){
document.getElementById('pageslist').innerHTML += '<span class=\"pageslistspan '+response.data[i].id+'\" onclick="showStatistics(this.classList[1])">'+response.data[i].id+' '+response.data[i].name+'</span>'+'<br>';
}
});
}
</script>
Try encapsulating your getPagesList inside document ready.
$(document).ready(function(){
getPagesList(){
...
}
});
I have a very basic question, I have the following code, I basically just trying to login to dailymotion.
window.dmAsyncInit = function()
{
DM.init({apiKey: 'MyAppID', status: true, cookie: true});
console.log('sdk loaded');
};
DM.Event.subscribe('auth.login', function(response)
{
// do something with response
if (response.status == 'connected')
{
console.log('connected');
testAPI();
}
else
{
DM.login(function(response)
{
if (response.session)
{
if (response.session.scope)
{
// user is logged in and granted some permissions.
// perms is a comma separated list of granted permissions
}
else
{
// user is logged in, but did not grant any permissions
}
}
else
{
// user is not logged in
}
}, {scope: 'read write'});
}
});
(function() {
var e = document.createElement('script'); e.async = true;
e.src = document.location.protocol + '//api.dmcdn.net/all.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(e, s);
}());
function testAPI() {
DM.api('/user/rs', {fields: "screenname"}, function(response)
{
alert('Name is ' + response.screename);
});
}
I have subscribed to auth.login, but I am not sure how I fire up this event. I want to create a login button for dailymotion and bind this event to the button. How can I do this?
You have to create a button which will fire a login function on the "onclick" event.
How to login is described at http://www.dailymotion.com/doc/api/sdk-javascript.html#sdk-javascript-method-login
Basically, you call the DM.login function, which will prompt the user to login (a pop-up window will appear for the user to log in).
Here I am unable to keep a user logged out once the user presses the logout button from my site. He is redirected to the login page but updateButton function is called again with same credentials he is getting logged in again. I tried several ways but the problem persists. I guess I am not doing things rightly in updateButton function down here and also FB.logout() is not being done correctly, as I get the error "FB.logout called without an access token" in the console.
The code is as follows:-
$(function(){
var button;
window.fbAsyncInit = function(){
FB.init({ appId : 'myAppId',
status : true,
cookie : true,
xfbml : true,
oauth : true
});
function updateButton(response) {// I am not sure I am doing it right here
console.log("Update Button Fired.");
console.log(response);
button = document.getElementById('fb-auth');
if(response.status === 'connected')
{
FB.api('/me', function(info)
{
login(response,info);
});
}
else
{
FB.login(function(response)
{
if(response.status === 'not_authorized')
{
FB.api('/me', function(info){
login(response, info);
});
}
else
{
}
}, {scope:'email, user_birthday,user_about_me' });
}
}
}
FB.getLoginStatus(updateButton);
FB.Event.subscribe('auth.statusChange', updateButton);
};
(function() {
var e = document.createElement('script');
e.async = true;
e.type = 'text/javascript';
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
})();
function login(response,info){
console.log('login Showloader called');
if (response.authResponse) {
var accessToken = response.authResponse.accessToken;
$.post("/web/register/faceBookRegistration",{ data:info,accessTokenValue:accessToken}).done( function(data){
if(typeof(data) != undefined){
window.location = "/web/login/loadViewFaceLogin";
}
});
}
}
function logout(response){
FB.logout(function(response){
console.log("User is now logged out");
});
}
});
Also I think my logout i.e
function logout(response){
FB.logout(function(response){
console.log("User is now logged out");
});
}
is not correct. In the console it shows that FB.logout called without an access token. What could be the reason
I took the liberty to rewrite your code, keeping your bases:
// File - fb-init.js
window.fbAsyncInit = function() {
FB.init({
appId : app_id,
status : false,
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));
-
// File - main.js
$('#fb-login').on('click', function() {
FB.getLoginStatus(function(responseStatus) {
if (responseStatus.status === 'connected') {
FB.api('/me', function(responseMe) {
if (!responseMe.id)
return false;
var accessToken = responseMe.authResponse.accessToken;
$.post('/web/register/faceBookRegistration' {
data : responseMe,
accessTokenValue : accessToken
}).done(function(data) {
if (typeof(data) !== 'undefined')
window.location = '/web/login/loadViewFaceLogin';
});
});
}
else if (responseStatus.status === 'not_authorized') {
FB.login(function(responseLogin) {
FB.api('/me', function(responseMe) {
if (!responseMe.id)
return false;
var accessToken = responseMe.authResponse.accessToken;
$.post('/web/register/faceBookRegistration' {
data : responseMe,
accessTokenValue : accessToken
}).done(function(data) {
if (typeof(data) !== 'undefined')
window.location = '/web/login/loadViewFaceLogin';
});
});
}, {scope:'email, user_birthday,user_about_me' });
}
else
return false;
});
});
$('#fb-logout').on('click', function() {
FB.logout(function(responseLogout) {
});
});
Because of the status set to true. If the current user is already logged on Facebook, it forces his auto-login on the website.
Anyway, it's not a good idea to use the FB.logout(), except if you want to force the user to logout from Facebook (And not your website).
About the popup, I think it's because of FB.getLoginStatus(updateButton); which calls the function updateButton() on every page loads.
You should improve it through an onclick function.
As I saw this Post FB.logout() called without an access token it confirmed what I always was on my mind that my Logout is not being done properly. If that get done I would be okay.
Here is the logout function code which did it for me :-
function logout(response){
if(!response.authResponse){
window.location = "/web/login/";
return;
}
FB.logout(function(response){
FB.Auth.setAuthResponse(null,'unknown');
logout(response);
});
}
As in the above link its been said that we should be keep sending logout request till its destroyed at the Facebook side. I made it a recursive call and the way out was when the the check confirmed it.
I am a noob and would only be glad if somebody working on the present solution builds a more elegant hack.
Thanks to 'ZeNy' too.
I'm trying to check if a user has logged in using facebook and get that error in JS console. My code looks like this:
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function () {
FB.init({
appId: '######', // App ID
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
xfbml: true // parse XFBML
});
};
// 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));
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
// the user is logged in and has authenticated 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 has not authenticated your app
} else {
// the user isn't logged in to Facebook.
}
});
</script>
What could be the problem and are there any sugestions on how to fix it?
In Chrome, you'd be getting the error: Uncaught ReferenceError: FB is not defined.
I like to trigger a custom event in Facebook's initialization function, fbAsyncInit().
Then I'm not limited to doing all my FB related scripting inside of the fbAsyncInit function. I can put it anywhere, by just listening for that custom event to be fired.
window.fbAsyncInit = function() {
FB.init({
appId : '123456789',
status : true,
cookie : true,
xfbml : true
});
$(document).trigger('fbload'); // <---- THIS RIGHT HERE TRIGGERS A CUSTOM EVENT CALLED 'fbload'
};
//MEANWHILE IN $(document).ready()
$(document).on(
'fbload', // <---- HERE'S OUR CUSTOM EVENT BEING LISTENED FOR
function(){
//some code that requires the FB object
//such as...
FB.getLoginStatus(function(res){
if( res.status == "connected" ){
FB.api('/me', function(fbUser) {
console.log("Open the pod bay doors, " + fbUser.name + ".");
});
}
});
}
);
You are calling FB.getLoginStatus before the SDK is loaded and/or initialized. To wait for that, that’s what the fbAsyncInit event is for. So put the method call in there.
I used the following simple approach and it works correctly:
In the head section I load the SDK:
<script type="text/javascript" src="//connect.facebook.net/en_US/sdk.js"></script>
Then in the body of your page where your actual content is, I used this:
<script>
function statusChangeCallback(response) {
console.log('statusChangeCallback');
console.log(response);
if (response.status === 'connected') {
testAPI();
} else if (response.status === 'not_authorized') {
FB.login(function(response) {
statusChangeCallback2(response);
}, {scope: 'public_profile,email'});
} else {
alert("not connected, not logged into facebook, we don't know");
}
}
function statusChangeCallback2(response) {
console.log('statusChangeCallback2');
console.log(response);
if (response.status === 'connected') {
testAPI();
} else if (response.status === 'not_authorized') {
console.log('still not authorized!');
} else {
alert("not connected, not logged into facebook, we don't know");
}
}
function checkLoginState() {
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
});
}
function testAPI() {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Successful login for: ' + response.name);
document.getElementById('status').innerHTML =
'Thanks for logging in, ' + response.name + '!';
});
}
$(document).ready(function() {
FB.init({
appId : '1119999988888898981989819891',
xfbml : true,
version : 'v2.2'
});
checkLoginState();
});
</script>
Simply using script with facbook sdk directly in tag
<script type="text/javascript" src="//connect.facebook.net/en_US/all.js#xfbml=1&appId=YOUR_APP_ID" id="facebook-jssdk"></script>
We were facing the same issue, and since FB sdk was not loading (or loading with delays) this was causing problems (or breaking javascript)in some cases which were dependent upon that.
To resolve this issue, we delegated all the calls related to facebook.
We created a function like :
function callOnFBSDKLoad(callback){
if (window.isFBInitialized) {
callback();
}
else {
jQuery(document).bind('fbInitialized', callback);
}
}
Where fbInitialized is a custom event learn more about custom events here.
And window.isFBInitialized is a variable set when SDK is loaded.
callback is the method enclosing FB related events.
e.g.
var FBLogin = function(){
FB.login(...);
}
callOnFBSDKLoad(FBLogin)
PS:
Please ignore syntax and naming conventions, I am basically sharing the idea to resolve such issues.
A simpler and solid solution. Call a function when the SDK loads. I will name it triggerLoginCheck().
<script>
window.fbAsyncInit = function() {
FB.init({
//TO DO: Add your unique Facebook app ID (All numbers).
appId : '***unique_app_id***',
cookie : true,
xfbml : true,
version : 'v2.8'
});
//Call the function here
triggerLoginCheck();
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 = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
Later, anywhere, place this:
function triggerLoginCheck() {
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
console.log(response);
});
}
It's work fine for me. Is necessary include the Object "Log.info.bind".
var Log = { info: { bind: function(){ alert('Hi'); testAPI(); } } }
I have this code on my website. The facebook login dialog is being shown when my page has loaded and not when the user has click on an anchor tag.
<script>
// Additional JS functions here
window.fbAsyncInit = function() {
FB.init({
appId : 'xxxxxxxxxxxxxx', // App ID
channelUrl : '//192.168.1.127/test/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
});
// Additional init code here
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
// connected
} else if (response.status === 'not_authorized') {
// not_authorized
login();
} else {
// not_logged_in
login();
}
});
};
function login() {
FB.login(function(response) {
if (response.authResponse) {
testAPI() ;
} else {
// cancelled
}
});
}
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>
I want the FB.getLoginStatus event to be fired up whenever the user click on this:
Login
But right now it's being loaded without me doing anythings.
Suggestions?
Ok so there is a simple solution here - wrap the call to FB.getLoginStatus in another function and have your button call that function.
function doLogin(){
FB.getLoginStatus(function(response) {
...
};
}
Then you can change the onClick on your button to doLogin().
Bassicaly, what was happening here is that as soon as the Facebook SDK is loaded, it calls the window.fbAsyncInit function which contained your FB.getLoginStatus code, so as soon as the SDK was ready, the login code was being executed.