I am trying to build a facebook page tab application using Meteor and have spent an ungodly amount of time just trying to receive a signed_request using just JS. This is incredibly easy using php but I can't use php inside of a Meteor app.
I'm loading the JS SDK within my if (Meteor.isClient) {} Section and it appears to be working. I've tried using FB.Login to get the information I need (Has User Liked Page, Is Admin, ect) but I can't seem to get it working. With page tab applications a user doesn't need to authenticate the app it just runs. The admin is the only that authenticates while installing I think... I can't find anything helpful perusing the Facebook Developer section on creating a facebook page tab application using the JS SDK. Please Help!
Some of my code...
if (Meteor.isClient) {
Template.fbconnect.connect = function () {
if (!Session.get("is Facebook JDK loaded?")) {
Session.set("is Facebook JDK loaded?", true);
// https://developers.facebook.com/docs/reference/javascript/
window.fbAsyncInit = function() {
// init the FB JS SDK
FB.init({
appId : 'Removed', // App ID, Took away for online question
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// Additional initialization code such as adding Event Listeners goes here
FB.getAuthResponse(function(response) {
if (response.status === 'connected') {
console.log(response.session.access_token);
} else {
console.log('User cancelled login or did not fully authorize.');
console.log(response.session.access_token);
}
}, {scope: 'email,user_likes'});
Related
i am currently building a website and my Wordpress theme already supports login to Facebook via the JS SDK. Below is my FB.init
window.fbAsyncInit = function(){
FB.init({
appId : 'xxxxxxxx'
, status : true
, cookie : true
, xfbml : true
, oauth : true
, version : 'v2.2'
});
};
Since i want to do some background checks before outputting stuff on HTML i'm also using the PHP SDK. ( I do not use the PHP for login purposes due to having more redirects while the JS one is straight forward (pop up and you're done).
To make the requests i am using the FacebookJavascriptLoginHelper with the below code to get the session i need for the request.
$helper = new FacebookJavaScriptLoginHelper();
try {
$session = $helper->getSession();
} catch(FacebookRequestException $ex) {
// When Facebook returns an error
} catch(\Exception $ex) {
// When validation fails or other local issues
}
All good so far. Each time i refresh the page i'm getting a new access token from the JS SDK and use it in the case i need to make a request.
Problem is on the logout part of all this.
If i use the FB.logout the user is logged out of the facebook, even in his browser and has to login again which is absolutely not acceptable.
I can by pass this "issue" by simply checking if there is a logged in user before going on and start asking for new Facebook sessions but is that the way i should go ?
When i loggout of the wordpress i can still receive access tokens and make requests to the server for some time. Close to 10-15 minutes i think. After that i do not receive anything and have to log in again.
EDIT: Also i noticed that even if i don't log out, if i don't refresh for a short period of time i get no session (access token). If i refresh once and then the second time i do get one
UPDATE:
In the end, I ended up imlementing using apache cordova/phonegap via Eclipse for android and xcode for iOS. This is the only solution that works on my preferred set up.
Link to download the plugin and documentation: https://github.com/phonegap/phonegap-facebook-plugin
Previous post:
I would like to implement facebook login into my hybrid apps. I already did few research in facebook documentation but I haven't found anything that works. If you can provide me some tips, that would be very helpful. I will reward a bounty for someone who can tell me how to do it.
I don't want to go through Phonegap/cordova and other framework since it would need me a lot of time to study those framework.
Hybrid apps - like native apps, run on the device, and are written with web technologies (HTML5, CSS and JavaScript). Hybrid apps run inside a native container, and leverage the device’s browser engine (but not the browser) to render the HTML and process the JavaScript locally. A web-to-native abstraction layer enables access to device capabilities that are not accessible in Mobile Web applications, such as the accelerometer, camera and local storage.
If anyone has any solution and willing to help, please let me know.
I've tried Javascript SDK but no luck.
Code:
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'xxxx', // App ID
channelUrl : '//xxxx/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
});
// 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();
}
});
};
// 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"; */
js.src="https://connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
// 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 + '.');
});
}
</script>
<!--
Below we include the Login Button social plugin. This button uses the JavaScript SDK to
present a graphical Login button that triggers the FB.login() function when clicked.
Learn more about options for the login button plugin:
/docs/reference/plugins/login/ -->
<!-- <fb:login-button show-faces="true" width="200" max-rows="1"></fb:login-button> -->
<!-- End script of Facebook Login -->
Are you currently testing it from your local computer or hosting the HTML on a server?
if on a server - what is your domain?
update it on the app domains (see image)
update it on section "Website with Facebook Login"
for testing the issue, remove FB.api call from testAPI(). just put an alert.
test it from a standard browser. If it works - nothing is wrong with your FB definition.
Instead of FB.Event.subscribe
use FB.getLoginStatus
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;
FB.api('/me', function(response) {
console.log(response);
});
} 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.
}
});
Reference link: https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/
I stumbled across a different solution which is working really well for me, and even better, no native code libraries! The trick here is to bypass the Facebook JavaScript SDK library and use the Facebook REST api endpoints directly.
I am using OpenFB javascript library (https://github.com/ccoenraets/OpenFB) to make this job easier, rather than write the calls all myself, but you can do it either way. I've outlined the steps on how to get it to work below.
1) Create a Facebook app and update the URL settings under Basic and Advanced to allow callbacks using facebook or your local urls. Then copy the Facebook ID ready for the next step
2) If you haven't already, download and install Cordova to put the tools in your command line. Then navigate to your Sites folder and run the following commands to create the project and add your platforms:
cordova create your-project-name
cordova platform add ios
cordova platform add android
3) Now we need to add a Cordova plugin to handle pop-up windows from facebook logins. To add a plugin use the command:
cordova plugin add org.apache.cordova.inappbrowser
4) Now we just need to download and configure OpenFB inside our new Cordova project. For this example we will just use the test page they provide, so download it from the OpenFB Github page and extract the files into your cordova project /www/ folder. After this open the index.html and edit the following line with your Facebook App ID from step 1:
openFB.init({appId: 'YOUR_FB_APP_ID'});
5) You should now be able to run the example and login using your local browser setup.
6) To test on iOS simulator you will need xCode installed then run the command:
cordova emulate ios
To test on an android emulator you will need the Android SDK installed and then run the command:
cordova emulate android
To test on an iOS device connected with a cable, run following command:
cordova run ios
To test on an Android device connected with a cable, run following command:
cordova run android
I'm trying to integrate both the Facebook login button and the comments plugin on my page.
I have them working separately, and when someone logs in via the login button, the comments plugin responds (and logs the user in), but my issue is the other way around; when someone logs in to post a comment via the comments plugin, there is no event to pass to the login button from the comments plugin.
Is there any way around this?
Thanks,
You should register to a FB javascript event on comment, or better yet to login. The login event should be triggered when the user logs in from a like or comment action:
window.fbAsyncInit = function() {
FB.init({
appId : 'xxxx',
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.login', function() {
/*create a reload in wich you login the user, because now you have the cookie. Or via ajax */
});
}
I'm writing a webapp where users will need to login with Facebook (a Facebookless login does not make sense in the context of the app). Ideally, after their initial visit, when a user visits /index, my webapp sees a cookie it deposited earlier, and seamlessly logs the user in automatically and goes to the application (/app).
My problem arises when the user logs out of Facebook, and returns to my app. Since their cookie on my domain will still be present, and their oauth_token will still be valid (they are for 60 days now), I can still log the user in automatically, and the app will work as expected.
To me, it doesn't seem right that the app remains signed in with their Facebook account even when they are not signed in to Facebook. I played around on Stackoverflow itself; it allows this behaviour as well. Are my worries misplaced, or is there a recommended way to see if a user is signed into Facebook when they first request /index from my server.
In my opinion, I don't think your app should remain signed in while the user has already signed out of Facebook.
One scenario where this may not be desirable is: what if I am using your app from a public computer. After I logged out of Facebook, your app still "remembers" me. And now anyone who uses this computer will assume my Facebook identity inside your app.
I think the problem here is that you set your own cookie to remember the user's Facebook login status. Obviously, when user signes out of Facebook itself, your cookie is not cleared. So at this point your cookie is out of sync with Facebook status.
I recommend that you don't use your own cookie for the purpose of remembering user's Facebook login status. Always rely on Facebook itself for this purpose.
The general strategy is, whenever user comes to your app, you should check the Facebook login status by using the mechanism provided by Facebook. This way, your app will be in syn with Facebook in terms of user's login status.
I personally use this piece of code to call Facebook Javascript API for the purpose of user login:
/*
* Init code for Facebook connect
*/
window.fbAsyncInit = function() {
FB.init({
appId : FACEBOOK_APP_ID, // App ID
channelUrl : CHANNEL_URL, // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true, // parse XFBML
oauth : true
});
// check facebook login status
FB.getLoginStatus(function(response) {
console.log("FB login status: " + response.status);
if (response.status === 'connected') {
showWelcome(); //display welcome message
} else if (response.status === 'not_authorized') {
// the user is logged in to Facebook, but not connected to the app
showFbLogin(); //display Facebook Login button
} else {
// the user isn't even logged in to Facebook.
showFbLogin(); //display Facebook Login button
}
});
// subscribe to facebook events
FB.Event.subscribe('auth.authResponseChange', function(response) {
fbAuthResponseChanged(response);
});
};
Users have been able to log into my website using their Facebook account, but then it suddenly stopped working properly.
I use the following standard Facebook JavaScript SDK code:
window.fbAsyncInit = function() {
FB.init({
appId : '<MY_APP_ID>',
status : true, // check login status immediately
cookie : true, // enable cookies to allow the server to access the session
xfbml : false // because I don't use XFBML
});
FB.login(function(response) {
// code that deals with `response`, whether null or not
});
}
But if I cleared the browser cache, and triggered this code (after the Facebook library had loaded), the following would happen:
Facebook's login dialog would pop up.
After entering credentials of a user that has access to this Facebook app, a dialog would ask whether I want to register a new login location.
Regardless of the action taken in the previous step, the dialog box displays the following error message:
An error may have occurred as part of the login process. You can close this window and try returning to the application, though it may ask you to log in again. This is probably due to a bug in the application.
FB.login's response contains an error message. Inspecting the browser's state, I can see that login information is stored within a Facebook cookie. Triggering the above code again, without clearing the cache, now succeeds.
Why doesn't it work the first time around?
Due to Facebook's OAuth 2.0 and HTTPS Migration, not using OAuth 2.0 after October 1, 2011 within JavaScript SDK will not work (properly).
To make the above example work, make sure that:
your FB.init call sets oauth to true (see example usage):
in the code that deals with the response:
you are reading the authResponse (not session) field of the FB.login's response;
you are calling FB.getAuthResponse (not FB.getSession), and reading signedRequest from its response.