I am trying to implement a simple login with facebook SDK functionality within a website that uses VueJS2.0.
The code that I have in the component that handles this is basically taken from FB SDK Quickstart:
onLoginPress() {
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
console.log('Logged in.');
} else {
FB.login(function(response) {
if (response.authResponse) {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + response.name + '.');
});
} else {
console.log('User cancelled login or did not fully authorize.');
}
});
}
});
Now I wonder - how should I provide the response from FB api back to the VueJS? I see that this inside those function calls points at the Window, but I dont have access to Vue.
Vue is initialized with the following code:
/* eslint-disable no-new */
new Vue({
el: '#app',
render: h => h(App)
})
This is window there because the function that the FB executes is done within the global context.
To solve this, in the line before the first FB assign a variable to this, which will be your reference to the Vue instance.
let vm = this:
FB......
Then you can do normal dispatches and such from Vue via vm.someMethod()
Related
I'm completely new in ReactJS and just wanted to play around and test some things out. I was looking into how to implement Facebook API, but getting this error message:
error 'FB' is not defined no-undef
Wasn't sure how to go about fixing this. Would like to seek help to see what I'm doing wrong here. Am I supposed to import some kind of Facebook API?
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
componentDidMount() {
window.fbAsyncInit = function() {
FB.init({
appId : '123141151155', //random app number
cookie : true, // enable cookies to allow the server to access
// the session
xfbml : true, // parse social plugins on this page
version : 'v2.3'
});
//JS SDK initialized, now you can use it
FB.XFBML.parse();
// Now that we've initialized the JavaScript SDK, we call
// FB.getLoginStatus(). This function gets the state of the
// person visiting this page and can return one of three states to
// the callback you provide. They can be:
//
// 1. Logged into your app ('connected')
// 2. Logged into Facebook, but not your app ('not_authorized')
// 3. Not logged into Facebook and can't tell if they are logged into
// your app or not.
//
// These three cases are handled in the callback function.
FB.getLoginStatus(function(response) {
this.statusChangeCallback(response);
}.bind(this));
}.bind(this);
// 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/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
}
// Here we run a very simple test of the Graph API after login is
// successful. See statusChangeCallback() for when this call is made.
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 + '!';
});
}
// This is called with the results from from FB.getLoginStatus().
statusChangeCallback(response) {
console.log('statusChangeCallback');
console.log(response);
// The response object is returned with a status field that lets the
// app know the current login status of the person.
// Full docs on the response object can be found in the documentation
// for FB.getLoginStatus().
if (response.status === 'connected') {
// Logged into your app and Facebook.
this.testAPI();
} else if (response.status === 'not_authorized') {
// The person is logged into Facebook, but not your app.
document.getElementById('status').innerHTML = 'Please log ' +
'into this app.';
} else {
// The person is not logged into Facebook, so we're not sure if
// they are logged into this app or not.
document.getElementById('status').innerHTML = 'Please log ' +
'into Facebook.';
}
}
// This function is called when someone finishes with the Login
// Button. See the onlogin handler attached to it in the sample
// code below.
checkLoginState() {
FB.getLoginStatus(function(response) {
this.statusChangeCallback(response);
}.bind(this));
}
handleClick() {
FB.login(this.checkLoginState());
}
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
);
}
}
export default App;
I've encountered the same issue and come up with another solution.
'FB' is not defined no-undef can be solved by referencing it from window, namely using window.FB instead of just FB. This work around does not need to install any additional npm package.
Here is a working repo of integrating the component into a React project, and in src/App.js you'll find the same code snippet above, and namely in the Stack Overflow question: Implement Facebook API login with reactjs
.
Providing this alternative solution as an additional option and I hope it helps.
Accourding to the documentation, you are missing to import/require the lib. I think you just need to import the file at the begining like:
import FB from 'fb';
I Hope it helps
When popup for access closed, browser blocking new popup for share. It is possible to give the right and open the window share? (without blocked popup)
$.ajaxSetup({ cache: true });
$.getScript('//connect.facebook.net/en_US/sdk/debug.js', function(){
FB.init({
appId : '856902511027949',
status : true,
cookie : true,
xfbml : true,
oauth : true,
version : 'v2.2'
});
});
function shareViaFbApp() {
FB.ui({
method: 'share',
href: 'https://developers.facebook.com/docs/',
display: 'popup'
}, function(response){
console.log(response);
});
}
$(".init").on('click', function(event) {
event.preventDefault();
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
shareViaFbApp();
} else {
FB.login(function(response) {
console.log(response);
if (response.authResponse) {
shareViaFbApp();
} else {
console.log('User cancelled login or did not fully authorize.');
}
}, {scope: 'publish_actions'});
}
});
});
I see only one way to get around this problem, create a block like fb popup share after FB.login(), and make share via FB.api().
You should not use FB.login in the asynchronous callback of FB.getLoginStatus. I know that it´s in an example in the Facebook docs, but it´s wrong and modern browsers block it. Use FB.getLoginStatus on page load (to refresh a user session and to check if a user is logged in) and FB.login directly on user interaction (mouse click).
You should not use FB.ui automatically either, only on direct user interaction like FB.login.
Btw, you don´t need to authorize a user for FB.ui, it will work without FB.login too.
So, i find workaround, if you need show share dialog after providing access to your fb app, use display: 'iframe' for this.
function shareViaFbApp(afterAccess) {
var display;
if (afterAccess) {
display = 'iframe';
} else {
display = 'popup';
}
FB.ui({
method: 'share',
href: 'https://developers.facebook.com/docs/',
display: display
}, function(response){
console.log(response);
});
}
$(".init").on('click', function(event) {
event.preventDefault();
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
shareViaFbApp();
} else {
FB.login(function(response) {
console.log(response);
if (response.authResponse) {
shareViaFbApp(true);
} else {
console.log('User cancelled login or did not fully authorize.');
}
}, {scope: 'publish_actions'});
}
});
});
I have this js:
$(document).ready(function () {
$('.login-link').click(function () {
FB.login(function(response) {
console.log(response);
if (response.authResponse) {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(resp) {
console.log('Good to see you, ' + resp.name + '.');
});
} else {
console.log('User cancelled login or did not fully authorize.');
}
}, {scope: 'email'});
});
});
which is bound to <div class="login-link">FB modal login</div>
The problem is when I click the button the FB.login and authorize the app the response.authResponse is null and response.status is not_authorized. If I click it again or refresh the page it shows user has authorized the app but obviously I need it the first time. The code is taken from Facebook with minor modifications.
Any ideas how to solve this?
Just wanted to show a workaround on this issue if someone else is also struggling on it.
$(document).ready(function () {
$('.login-link').click(function () {
FB.login(function(response) {
FB.getLoginStatus(function (resp) {
console.log(resp);
}, true);
}, {scope: 'email'});
});
});
I leave my question open because it doesn't really answers the question why FB.login is not working but at least provides a temporary solution.
I am using backbone.js to implement a login page with a facebook login button.
window.LoginPage = Backbone.View.extend({
initialize:function () {
this.template = _.template(tpl.get('login-page'));
},
render:function (eventName) {
$(this.el).html(this.template(this.model.toJSON()));
this.bind("nav", this.nav,this);
this.model.bind("reset", this.render, this);
return this;
},
events:{
"click #login":"login"
},
login:function(){
FB.login(
function(response) {
if (response.authResponse) {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + response.name + '.');
}
);
} else {
console.log('User cancelled login or did not fully authorize.');
}
},
{ scope: "email" }
);
}
});
This works, I can login with my facebook app. But after the login I want the FB.event.subscribe to be triggered. But I do not have a clue how to implement this with backbone.js
FB.Event.subscribe('auth.login', function(response) {
Backbone.history.navigate("#locallist",true)
});
Not sure what you mean with "I want the FB.event.subscribe to be triggered". If you have the FB object on your window, you can just start binding events wherever.
I think your problem will be that you can't guarantee when or if the FB object is on the window, so something that I have in my applications is to create a global event and make my app listen to that event. Here's some pseudo-code in CoffeeScript:
class FacebookServiceProvider extends ServiceProvider
constructor: ->
super
initialize: (options) ->
FB.init
appId: appId,
status: true,
cookie: true,
xfbml: true,
oauth: true
app.trigger 'facebook:initialized'
window.facebookInitialized = true
#
class FacebookView extends Backbone.View
initialize: (options) ->
if window.facebookInitialized
onFacebookInitialized.call #
app.on 'facebook:initialized', #onFacebookInitialized, #
#
onFacebookInitialized: =>
FB.Event.subscribe 'auth.authResponseChange', (response) -> console.log response
#
basically just using a global variable on the window to see whether the facebook service provider has been initialized and if so, depending on the state, my view will render or listen to FB events only when it can and no sooner.
so after updating to the php 3.0 sdk and what not, my FB.login() function no longer asks for the permissions I set it to ask. Any one else getting this? Here's some code for you:
window.fbAsyncInit = function() {
FB.init({
appId: 'xxx',
status: true,
cookie: true,
xfbml: true,
oauth : true // enables OAuth 2.0
});
// whenever the user logs in, we refresh the page
//FB.Event.subscribe('auth.login', function() {
// window.location.reload();
//});
};
FB.login(function(response) {
if (response.authResponse) {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + response.name + '.');
FB.logout(function(response) {
console.log('Logged out.');
});
});
} else {
console.log('User cancelled login or did not fully authorize.');
}
}, {scope:'read_stream,publish_stream,offline_access'});
The way I'm trying to access it, is through an onClick="FB.login();". Can anyone help?
Checking the source of the JS SDK I found that they still use perms and not scope as it it documented.
This is working for me:
...onclick="FB.login(handleLoginResponse,
{perms:'email,manage_pages,user_birthday'});return false;"...
I hope it helps.
I see something related to this with the JS SDK. When setting oauth=true, the function
FB.login(function (response) {
if (response.authResponse) {
console.log('Welcome! Fetching your information.... ');
} else {
console.log('User cancelled login or did not fully authorize.');
}
}, { scope: 'email,publish_stream,user_birthday,user_location' });
Correctly requests the extended permissions, but using the <fb:login-button> FBXML with scope="email,publish_stream,user_birthday,user_location" does not.
This looks like a Facebook bug to me...
My problem was similar to you.
I have checked all my javascript to verify if my scope was good in FB.login definition.
Finally I realized that I have a Facebook button in my HTML.
<form class="form-signin"><fb:login-button size="large">Facebook</fb:login-button></form>
When I have also defined the scope in the FB Button, Facebook ask me correcty to accept new permissions if I change my scope
<form class="form-signin"><fb:login-button size="large" scope="<?php print($sFacebookScope);?>">Facebook</fb:login-button></form>
I think its because you are calling FB.logout within the FB.login block.
Effectively what happens is as soon as they log in, they are logged out.
So seperate it like this:
// CALLED WHEN USER LOGS IN
function userLogin() {
FB.login(function(response) {
if (response.authResponse) {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + response.name + '.');
});
} else {
console.log('User cancelled login or did not fully authorize.');
}
}, {scope:'read_stream,publish_stream,offline_access'});
}
// CALLED WHEN USER LOGS OUT
function userLogout() {
FB.logout(function(response) {
console.log('Logged out.');
});
}
I had exactly the same problem until I realized that it was a matter of browser/facebook caching problem. Make sure you have the latest code in your webspace and test your app in a new browser if might be the solution of your problem.
The only solution that has worked for me was putting the permissions in the login button tag like this:
<fb:login-button show-faces="true" width="200" max-rows="1" data-scope="email">< /fb:login-button>