I am trying to use Facebook API for likes on my web page. Currently trying to use all.js, it fails to load the file at url below as it translates it to file://connect.
//connect.facebook.net/en_US/all.js#xfbml=1
Changing url explicitly to http: gives a different error.
Do we need APPID for initializing this API and use all.js or can it be used without APPID?
Reference URL:
http://developers.facebook.com/docs/reference/plugins/like/
According to this answer, an AppId is required. The tool in the reference URL you listed will insert your AppId in the code it generates.
(function(d, s, id) {
...
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=xxxxxxxx";
...
}(document, 'script', 'facebook-jssdk'));
You are probably getting the file://connect error because you are testing by opening a local file in your web browser instead of a file served by a real web server. When you don't specify the protocol in a link, the browser will assume it's the same protocol as the current page.
From the Facebook documentation:
Note: The URLs in the code are protocol relative. This lets the
browser load the SDK over the same protocol (HTTP or HTTPS) as the
containing page, which will prevent "Insecure Content" warnings.
Missing http and https in the code is intentional.
Related
I am getting an error message when attempting to use the Facebook API.
When I have Client OAuth Login enabled, Web OAuth Login enabled and a valid Oauth redirect URI set to http://localhost:8000/ the error I get is this when trying to log into Facebook with the correct App ID:
URL Blocked: This redirect failed because the redirect URI is not whitelisted in the app’s Client OAuth Settings. Make sure Client and Web OAuth Login are on and add all your app domains as Valid OAuth Redirect URIs.
Is there a particular setting or thing I have to put in code to get this to work correctly?
This is the code I've got:
$(window).load(function() {
if (window.cordova.platformId == "browser") {
facebookConnectPlugin.browserInit(MYAPPIDHERE);
}
});
And this:
facebookConnectPlugin.login(["user_likes"],
function(response) {
likes();
},
function(response) {
likes();
});
}
EDIT:
Added pictures of what is in the Facebook App, as well as the URL I am navigating from.
You might want to check for HTTP calls made by facebookConnectPlugin and see if the redirect_uri in the query string matches the one you have in your Facebook App settings as a valid redirect URI.
It might look something like this:
https://www.facebook.com/dialog/oauth?client_id={FB_APP_ID}&redirect_uri=http://localhost:8000/
EDIT:
There seems to be an issue with the redirect_url=http://static.ak.fbcdn.net/connect/xd_proxy.php#cb=f11b73fd18e512c# being used by facebookConnectPlugin. I checked the javascript code and it is using phonegap/plugin/facebookConnectPlugin/fbsdk.js, which seems to be the culprit.
When I used direct loading of FB SDK, it uses a different redirect_url=http://staticxx.facebook.com/connect/xd_arbiter/r/RYqXvcNXPI-.js?version=42. Replacing the previous redirect_url with this one solved the issue for me. It is possible that phonegap's fbsdk.js uses an outdated script.
Bottomline: It would be better to load FB SDK directly, as mentioned here. And according to FB docs, it would look like this:
<script>
(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>
Lastly, to enable debug logs, replace //connect.facebook.net/en_US/sdk.js to //connect.facebook.net/en_US/sdk/debug.js.
The Javascript API wont work on PhoneGap for the login.
Use this cordova plugin instead.
https://github.com/Wizcorp/phonegap-facebook-plugin
It is impossible for Facebook to redirect to a local URL. What will happen is that you redirect a user to Facebook, they login, Facebook validates this and sends them back to you. Facebook sends them to the URL you provide. The URL http://localhost:8000 is a shorthand for: connect to port 8000 on your own machine. At the point where Facebook does the redirect, localhost refers back to Facebook, not you anymore. Apparently, Facebook has blacklisted that stuff - probably for security reasons.
What you need is a public URL that Facebook can redirect to. Maybe this helps?
Try these things:
set the URI to http://localhost/ (no port)
put a callback at the redirectURI with a corresponding callback function. i.e., http://localhost/loginCallback
Report back with any errors, I have a feeling the 1st way will work.
Like widget works, Comment widget does not: SEE UPDATE 2
I inherited a project which has a Graph 1.0 implementation. Users can log in with Facebook, and then Like and Comment on the site.
The authentication system (symfony/php) interacts directly with Facebook in order to identify the user so that, if they don't exist, a profile can be created or, if they do exist, they can be logged into the local system as well.
The Like and Comment widgets have been updated to use the 2.0 syntax:
window.fbAsyncInit = function() {
FB.init({
appId : 'KEY_HERE',
xfbml : true,
version : 'v2.3'
});
};
</script>
<script>(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/es_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
This seems to be working ok. Widgets are generated and, using my personal Facebook account, I can post and like and see the results on both this site and on Facebook.
Meanwhile, for authentication, the application generates an authorize url like this:
http://www.facebook.com/v2.3/dialog/oauth?client_id=API_KEY&redirect_uri=REDIRECT_URI&state=TOKEN&scope=SCOPE
Scope consists of the following:
'email', 'user_website', 'offline_access', 'status_update', 'publish_actions', 'publish_stream'
From the callback handler of that request, we retrieve the users Facebook profile and forward along to custom code for logging a user in, or registering them:
https://graph.facebook.com/v2.3/oauth/access_token?client_id=API_KEY&redirect_uri=REDIRECT_URI&client_secret=API_SECRET&code=CODE
This also appears to be working, as long as I'm using my personal FB profile. I can login and Comment and Like things.
When I log in using my Open Graph Test User, I can't Like or Comment. When try to post a comment, I get an error which simply states "Oops" in a lightbox/dialog. From my console, I get the following error:
for (;;);{"__ar":1,"error":1357010,"errorSummary":"Oops","errorDescription":"Something went wrong. We're working on getting it fixed as soon as we can.","payload":null,"bootloadable":{},"ixData":{},"lid":"0"}
Here's what appears to be a comprehensive list of error codes, but 1357010 is not listed:
[http://fbdevwiki.com/wiki/Error_codes][1]
So, the fundamental question is, why can my Open Graph Test User (configured to run the app in 2.0 mode) not interact with the widgets, while my personal FB profile can? Have I failed to properly upgrade the authentication system so that the 2.0 Test User isn't sufficiently privileged?
[UPDATE]
When my application logs a user in, there is no part of the FB dialog which permits a user to accept the permissions which are being requested. Regardless of whether I'm logged in with my personal account or the Graph Test User, I can Like a page and then, subsequently, Comment from the resulting dialog - that dialog requests permission to do so.
But, from the standard Comments widget, I'm never asked to grant permission to post - it just fails with error 1357010. Toggling on/off "Also post on Facebook" makes no difference.
Am I not authenticating in a 2.0 fashion?
[UPDATE 2]
It looks like my Open Graph Test User can Like a page, and then, after confirming, the user can Comment on the page form the resulting dialog from the Like widget.
However, from a Comment widget, the comment is not successful and I get the generic error code 1357010.
What do I need to do to authorize my OG Test User (v2.3 user) to submit comments from a standard Comments widget?
It's unclear what are the calls you are making and I believe by "Like and Comment Widgets" you are talking about custom ones that are powered by the API and not the official Facebook plugins.
So to the issue: test users CANNOT interact with real data as per the docs:
Each app can create a maximum of 2000 test users.
Test users can only interact with other test users, and not with real users on Facebook.com.
Test users cannot become a fan of a public Facebook Page or create content on them, such as writing on a Page's wall. A Test
user can however view and interact with any app tab on the Page
associated with the app that created them.
Test users are unable to reply to messages, even if the message was created by the test user.
Test accounts can only be accessed and used by any developer of the associated app.
Test users will only have 'Tester' privileges on the associated app. This means that they can use the app in Public Mode or
Development Mode, but cannot edit any technical settings or access
insights for that app.
Test accounts cannot be converted to normal user accounts.
If you are interacting with real data, this may not work. You could probably test this by creating a new test user and observe the results.
Friends,
I have set up a facebook login for my website using JS SDK.
If the use is logged in through JS SDK, should we cross verify whether the session is valid in the server side also as client side can easily be fabricated.
Since I use JS SDK, server will not have access to the facebook session.
If I need to verify the session at the server end, can i use php-sdk adn extern the session like it is specified in https://developers.facebook.com/docs/reference/php/ ? In this case I need to enable CURL PHP extension to get this running and worried if performance will go down when using php sdk.
Could you please help me in finding answers for the above queries?
The php sdk and the javascript are the completely opposite, of what Julian H. Lam said, in fact they were build to be used together.
On the php sdk documentation you can find this:
Integration with the Facebook SDK for JavaScript
Used in conjunction with the Facebook SDK for JavaScript, the PHP SDK
can share user sessions seamlessly across the client and server. If a
user is logged in with Facebook and has authorized your app, the
JavaScript SDK can pick up the user session persist this in a cookie
which, which the PHP SDK reads without any intervention on the
developer's part.
To enable this functionality, ensure that when you embed and
initialise the JS SDK, you set both the status and the cookie
parameters of the object passed to FB.init() to true.
And by using basic logic this makes all sense, on the client side you can create listeners to retrieve user status(if he's logged in, if he has granted permissions, if he has logout), doing this kind of actions on the server side doesn't make any sense at all.
So my advice for you is to use Javascript SDK to handle user events, like the ones I mentioned before, and to handle the responses from the actions of the users, like when the user does a like, or shares a post using the feed dialogue, etc.
With the php SDK you just check if you have a valid user, since you're sharing the same cookie for the client side and for the server side after you handle the login proccess with the javascript SDK, if you do this $fb_id = $facebook->getUser() (after initializing the PHP SDK of course), you'll get the user facebook id, now that you know you have a valid user, you can use the PHP SDK to query information about the user, post on user behalf, etc.
Here's an example of a proper loading of the javascript SDK with cookie support:
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
// init the FB JS SDK
FB.init({
appId : 'YOUR_APP_ID', // App ID from the app dashboard
channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel file for x-domain comms
status : true, // Check Facebook Login status
xfbml : true, // Look for social plugins on the page
cookie : true
});
// Additional initialization code such as adding Event Listeners goes here
};
// 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>
And this is a simple code on the server side just to enlighten you:
require_once("facebook.php");
$config = array();
$config[‘appId’] = 'YOUR_APP_ID';
$config[‘secret’] = 'YOUR_APP_SECRET';
$config[‘fileUpload’] = false; // optional
$facebook = new Facebook($config);
try {
$user_profile = $facebook->api('/me','GET');
$user_name = $user_profile['name'];
$user_email = $user_profile['email'];
} catch(FacebookApiException $e) {
// If the user is logged out, you can have a
// user ID even though the access token is invalid.
// In this case, we'll get an exception, so we'll
// just ask the user to login again here.
}
PS: this server side code, only works if the user has already granted permissions with the scope email
There are two parts to this question: Firstly, there is a difference in the UI flow. See: https://developers.facebook.com/docs/concepts/login/login-architecture/
1) Browser side with JS SDK. You start off with oauth 2.0 dialog, obtaining the Access Token and then using this to access the Facebook API.
2) Server side uses signed_request posted to the server. With this, you can extract the user_id. See: https://developers.facebook.com/docs/howtos/login/signed-request/ -
Step 1 - describe the signed_request, how you can obtain it from PHP or JS SDK
Step 2 - how to verify that the signed_request is not fabricated.
Oauth token from other providers can be integrated with FB. See my Dropbox example: apps.facebook.com/fileglu/ - circa Sept 2011, also check out the technical section for implementation details, including CSRF, CORS and avoiding javascript cryptography.
The Facebook javascript library and the php SDK can essentially be considered two entities that do not talk to one another, as one is client-side, and the other is server-side.
The php SDK gives you greater fine-grained control over a user's login session, while the javascript library is easier to get started.
Typically, a user logged in via the javascript library is not automatically logged in on the server side, although in some cases, it may be possible to send the access token from client to server side. It is not advised, however, as this data can be intercepted.
This related question talks about sending the access token (as retrieved from the JS library) to the server side.
In essence:
FB.login(function(response) {
var access_token = response.authResponse.accessToken;
// Make an ajax call here to your server-side, and send access_token in.
});
I'm using FB.ui() like so:
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '##########', // App ID
channelUrl : '//www.xxxxxxxxxx.com/channel.php', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// Additional initialization code here
};
// 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>
Then, here's the link to send the message:
<a href='#' onClick="
FB.ui({
method: 'send',
name: 'Bla bla bla',
link: 'http://www.xxxxxxxxxxx.com',
to: ###########,
//redirect_uri: 'http://www.xxxxxxxxxxx.com/fb/'
});
">Send a message</a>
PROBLEM:
This works like a charm for me and every computer/browser I've tested on. But my client gets the following error message very frequently:
API Error Code: 191
API Error Description: The specified URL is not owned by the application
Error Message: redirect_uri is not owned by the application
This has me totally stumped! Is anything wrong with my code? And if so, why can't I EVER reproduce this bug while my client consistently can on multiple computers/browsers?
PS: If you want to try yourself, the page is live here. You'll have to authorize the app, but I promise nothing creepy will happen.
EDIT: The error mentions the redirect_uri, which you'll notice is commented out in my code. The reason is because when I include that parameter, the dialogue doesn't close when I hit "close".
EDIT2: I was able to reproduce this bug on a friend's computer, and CBroe also confirmed it. So, (setting aside the mystery of why I still can't produce it myself), the thing that has me most stumped is why does this only happen half of the time?? If my code is incorrect it should never work, right??
Here's the url from the error message:
https://www.facebook.com/dialog/send?display=popup&link=http%3A%2F%2Fwww.streetofwalls.com&locale=en_US&name=Career%20Networking%20powered%20by%20Street%20of%20Walls&next=http%3A%2F%2Fstatic.ak.facebook.com%2Fconnect%2Fxd_arbiter.php%3Fversion%3D8%23cb%3Df2c657ef78%26origin%3Dhttp%253A%252F%252Fwww.streetofwalls.com%252Ff3575a615c%26domain%3Dwww.streetofwalls.com%26relation%3Dopener%26frame%3Df1ca46b43c%26result%3D%2522xxRESULTTOKENxx%2522&sdk=joey&show_error=true&to=573501273
After url_decode() version:
https://www.facebook.com/dialog/send?display=popup&link=http://www.streetofwalls.com&locale=en_US&name=Career Networking powered by Street of Walls&next=http://static.ak.facebook.com/connect/xd_arbiter.php?version=8#cb=f2c657ef78&origin=http%3A%2F%2Fwww.streetofwalls.com%2Ff3575a615c&domain=www.streetofwalls.com&relation=opener&frame=f1ca46b43c&result=%22xxRESULTTOKENxx%22&sdk=joey&show_error=true&to=573501273
EDIT3:
Part of this puzzle is solved. The times when the error occurs are the result of FB.init() not working. I've wrapped the FB.ui() in FB.getLoginStatus(function(response){ \\... } so now you can see a more useful error in the console. The open question is... WHY DOES FB.init() fail so often?
This is due to a configuration error between your redirect_uri and the settings that you have specified for your Facebook app. See the answer to this question.
The redirect_uri should be equal (or relative) to the Site URL that you set in your Facebook app's settings. So make sure your Site URL is set and that it points to a directory that is equal to or lower than your redirect_uri. Also, make sure you have set the app's domain correct in Facebook's settings.
For example:
App domain: streetofwalls.com
Site URL: / Secure Canvas URL: / Secure Page Tab URL: http://www.streetofwalls.com
First you load the following script in the head of your page:
<script type="text/javascript" src="http://www.streetofwalls.com/wp-content/themes/streetofwalls/js/main.js"></script>
Inside that script you try to load the FB JavaScript SDK asynchronously. The SDK requires the fb-root element in order to load properly as stated in the docs. But your fb-root element might not be rendered yet, so here is the problem I guess.
Put the window.fbAsyncInit = ... and the code for loading the SDK asynchronously inside jQuery(document).ready(function($) { ... }); and you should be fine.
For debugging you could also try to load the Facebook SDK synchronously.
Another thing I have noticed:
You have two script tags inside the head of your site which load the FB JavaScript SDK. You should remove both.
So Nitzan deserves the credit for this for his insightful comment, but here's the solution.
The error message I was getting was a result of the fact that FB.init() wasn't loading, or at least it wasn't loading in the proper order with respect to the rest of the page. I copied the code from the Facebook Developer docs and it loads asynchronously... which turns out to be kind of a big pain in the ass...
So instead of what I had, I switched to loading it the old fashioned way:
FB.init({
appId : '##########', // App ID
channelUrl : '//www.xxxxxxxxxx.com/channel.php', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
This, combined with some reordering of the other scripts, seems to have resolved my problem.
As stated in the Facebook Oauth Documentation, in order to use the Client Side Flow with a Desktop App, the special return_uri https://www.facebook.com/connect/login_success.html is required.
Opening a new tab from Chrome to the url
https://www.facebook.com/dialog/oauth?client_id=MYAPPID&redirect_uri=https://www.facebook.com/connect/login_success.html&response_type=token
works as expected, I am redirected to the login_success page with an access_token parameter containing the token. I can request data from the Graph API using simple GET requests (e.g., with jQuery):
$.getJSON("https://graph.facebook.com/me", {access_token : token}, function (d)
{
.. process returned data
});
My question is, can I continue to use the Javascript SDK without using the SDK's internal authorization methods.
FB.getLoginStatus returns an error that my Connect/Canvas URI isn't correct. How am I supposed to check the token status without that method [apart from a manual GET and response matching]?
FB.login obviously fails with the following error:
API Error Code: 191
API Error Description: The specified URL is not owned by the application
Error Message: Invalid redirect_uri
(url does not match domain url in the app's config), as there seems to be no way to internally specify the return_uri above.
Is there a way to still rely on the Javascript SDK (especially events) while accessing a token externally? Am I supposed to override the access token?
Yes, you can use it for the normal events (i.e. someone clicked a like button) like so:
<div id="fb-root"></div>
<script type="text/javascript" src="http://connect.facebook.net/en_US/all.js#xfbml=1" id="facebook-jssdk"></script>
<script type="text/javascript">
FB.Event.subscribe('edge.create',
function(response) {
console.log(response);
}
);
</script>
Unfortunately for regular API calls you can't use the Facebook JS SDK from within your extensions. You'll have to roll your own API wrapper for that.
An easy way to see if the access token is valid, is to make a graph API call to /me?fields=id with the access token you have saved. That will be fast and you can use the response to see if the access token is still valid. Best practice for extensions is to request the permission offline_access.
Also, I would recommend having the redirect URI be on a domain you own. That way if other extensions are doing the same, your scripts won't interfere. Accessing the token will be the same.