After creating a Facebook App, leaving it in Sandbox and attempting to setup a Share button using the Feed Dialog, it seems only FB accounts I've added as Admins are able to use the Share button - all other non-Admins are able to see the Feed Dialog popup, but are then seeing "An error occurred, please try again.".
I thought it was a browser specific issue but seems to be dependant on your FB accounts relationship with the App. A person who is a non-Admin has been testing the App and is unable to Share at all.
I am using Wordpress as a CMS backend for this App. As far as I can tell the App ID and App URL are all correct, the only difference is that being on my dev environment it will be moved to a clients production FB page once this is all working.
I find it very bizarre that it works excellent provided you are an Admin of the page. Could it be possible this is simply a Sandbox thing?
I also checked that trying to use the Share button when logged in as a Page as opposed to yourself was the issue, and it is not (if anyone was wondering).
I believe I am using the SDK/API and Feed Dialog correctly, but my code for reference:
header.php
<div id="fb-root"></div>
<script src="https://connect.facebook.net/en_US/all.js"></script>
<script type="text/javascript">
// Called when FB SDK has been loaded
window.fbAsyncInit = function () {
// Auto resize FB Canvas
FB.Canvas.setSize({height:600});
setTimeout("FB.Canvas.setAutoGrow()",500);
};
// Load the FB 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>
footer.php
<script type="text/javascript">
FB.init({
appId: '515010801895800',
status: true,
cookie: true,
xfbml: true
});
function postToFeed() {
var obj = {
method: 'feed',
display: 'popup',
picture: '<?php echo get_template_directory_uri(); ?>/images/app/app-icon-75.png',
name: 'Suncorp Brighter Futures Heroes',
caption: '',
link: 'https://www.facebook.com/aaronlepikdev/app_515010801895800',
description: 'Suncorp Brighter Futures Heroes is a place where our people come together to share their stories, raise money, volunteer and apply for grants for causes close to their hearts.',
actions: {name: 'Suncorp Brighter Futures Heroes', link: 'https://www.facebook.com/aaronlepikdev/app_515010801895800'}
};
function callback(response) {
document.getElementById('msg').innerHTML = "Post ID: " + response['post_id'];
}
FB.ui(obj, callback);
}
</script>
Any help at all is much appreciated.
It seems I indeed may have answered my own question - I have removed Sandbox and it seems to be working. I did stumble across this though: Sandbox Mode - Please note that when your app is in Sandbox Mode, you cannot call any API calls on behalf of users who cannot see your app.
Related
I am trying to tweak the Parse Express tutorial:
https://www.anyimg.org/ and https://github.com/ParsePlatform/Anyimg
Basically, instead of starting with their default home page, I always show a login page if the user has not been logged in. I was able to do that by adding a simple check for Parse.User.Current() at the Homepage endpoint and redirecting to login if they are not looged in.
For my next step, I want to allow Facebook login. So I tweaked the login.ejs as follows:
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
Parse.FacebookUtils.init({
appId : '254642391362596',
status : true,
xfbml : true
});
};
(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'));
function fLogin() {
/*Parse.FacebookUtils.logIn(null, {
*//*success: function(user) {
alert("login success with user " + JSON.stringify(user));
if (!user.existed()) {
alert("User signed up and logged in through Facebook!");
} else {
alert("User logged in through Facebook!");
}
//FB.api('/me', function(response) {
// alert("got fb me api=" + JSON.stringify(response));
//});
},
error: function(user, error) {
alert("User cancelled the Facebook login or did not fully authorize.");
}*//*
});*/
// log in with Parse
Parse.FacebookUtils.logIn(authData, {
success: this._fbLoginSuccess,
error: this._fbLoginError
});
}
</script>
<button class="btn-facebook btn-large" onclick="fLogin();"><img src="./images/FB-f-Logo__blue_58.png"> <span class="btn-facebook-text">Login with Facebook</span></button>
The good news: When I try the commented block without the login block, I get a FaceBook login prompt, and I can go to the DataBrowser and see AuthData there.
However, if I use the //Login block, nothing seems to happen.
Also, if FB login is a success what do I change in app.js or user.js to allow the home page to render? I have been searching docs and SO for a day now, and I don't see any clear docs on this.
Thanks for your help!
Note: I am rather new to both Parse and Express, but I have been able to make progress mostly on my own (please see my other postings here).
I have made progress. The code above essentially works. Remove unwanted alerts from above and use window.location.href = '"home"/one-of-my-routes". However, I am still unable to send a post to my users.js page. Any help will be appreciated
What you are trying to do is definitely possible (I've done it), but can't be achieved with the method you are using right now. Basically you can't access the Parse.User.current() in Express on the server if you do a login with Facebook JS SDK on the browser. It doesn't work. (See this question in Parse forums.)
The only way you can achieve what you want, as far as I know, is using the undocumented parseFacebookUserSession middleware.
Edit: Add step-by-step detailed instructions
To log in the user with Facebook on Express (server) you simply need to follow the steps detailed on the middleware's github repo. Start by adding the file parse-facebook-user-session.js into the cloud folder. Then add the code shown on the readme to app.js, like this:
var parseExpressHttpsRedirect = require('parse-express-https-redirect');
var parseExpressCookieSession = require('parse-express-cookie-session');
var parseFacebookUserSession = require('cloud/parse-facebook-user-session');
app.use(parseExpressHttpsRedirect()); // Require user to be on HTTPS.
app.use(express.bodyParser()); // Middleware for reading request body
app.use(express.cookieParser('123456789')); // YOUR_SIGNING_SECRET
app.use(parseExpressCookieSession({ cookie: { maxAge: 3600000 } }));
var fbLogin = parseFacebookUserSession({
clientId: 'FB_APP_ID',
appSecret: 'FB_APP_SECRET',
verbose: true,
redirectUri: '/profile' // where the user will be redirected to after getting a token from Facebook
});
// This route will require FB login. If the user is not logged in, it will be redirected to FB
app.get('/events/new', fbLogin, events.new);
// A route to log out
app.get('/logout', function(req, res) {
Parse.User.logOut();
res.redirect('/');
});
Some notes:
You must use HTTPS
You must enable the 'Add Field' Class Level Permission for the _User class using the Data Browser
You must enable 'Allow client class creation' in the app Settings (see the readme)
A new class ParseFacebookTokenRequest will be created on the Data Browser. Disable all it's Class Level Permissions (again, see the readme)
Important: According to a Parse Engineer, it's possible to log in the user client side using the FB JS SDK. I haven't done this but it's somewhat explained in this issue.
I recently found this useful post. Albert, this has the become() that you suggested. And this helped me at least get one version working.
Parse Javascript SDK -- Save client-side `user` as server-side ` Parse.User.current()`
I've seen a few posts here and around the interwebs explaining how to create a custom Facebook share dialog box for my website.
But I have found a few differences from the average situation to mine:
1- I want a custom area in my page to open and close when people click on a button (the share button)
2- I want share the content in a lightbox, not the page's content. For example, we have a list of products, each product will open in a lightbox. I want to share information about this product that is now open in a lightbox
I saw someone talking about the Javascript SDK, but it the installation guide it tells me to set the APP_ID, but don't have any App create for my website. Do I have to create one to use this SDK?
I also found this pattern
http://www.facebook.com/sharer.php?s=100&p[title]=a title&p[summary]=a description &p[url]=http://www.linkhere.com&p[images][0]=http://www.linkhere.com/image.jpg
If I copy and paste this to the address bar it works. but the user is redirected to a new page. that is not nice.
and I tried this with the pattern said above, but couldnt make it work
<a href="#"
onclick="
window.open(
'https://www.facebook.com/sharer/sharer.php?u='+encodeURIComponent(location.href),
'facebook-share-dialog',
'width=626,height=436');
return false;">
Share on Facebook
</a>
It doesn't accept the parameters I am trying to pass.
Do any of you know how to solve this problem? Will it be by changing the 'content' of metatags? What are your solutions?
#EDIT
Just answered with the solution I used
#EDIT 2
Updated with v2.2
This is an old question, but here is what works for me:
window.open(
'http://www.facebook.com/sharer.php?s=100&p[title]=a title&p[summary]=a description &p[url]=http://www.linkhere.com&p[images][0]=http://www.linkhere.com/image.jpg',
'facebook-share-dialog',
'width=626,height=436'
);
basically all I had to do was remove the /sharer/ from the facebook url. I am guessing it is a typo in the documentation.
This is what I did to solve the problem in my website:
First I added the tools Facebook provides me:
<script>
window.fbAsyncInit = function() {
// init the FB JS SDK
FB.init({
appId : 'YOUR APP ID GOES HERE', // App ID from the app dashboard
status : true, // Check Facebook Login status
xfbml : true // Look for social plugins on the page
});
// channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel file for x-domain comms
// 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>
Then I created a function shareOnFacebook that opens the sharer and the button that will call this function
var globalFacebookShareObject = {} //will be set when I click on a product, on a picture, on a comment or post, or whatever I want to share on Facebook or when I load the page
function shareOnFacebook(){
FB.ui({
method: 'feed',
name: globalFacebookShareObject.name,
link: globalFacebookShareObject.link,
caption: 'R$ '+globalFacebookShareObject.caption,
picture: globalFacebookShareObject.picture,
description: globalFacebookShareObject.description
}, function(response) {
if(response && response.post_id){}
else{}
});
}
<button onclick='shareOnFacebook()'>Share it!</button>
#edit at 10/01/2015
Still working for v2.2
Refere to Feed method to understand how to create the share dialog (I am using the feed method that seems to be more flexible)
And to Quickstart
To understand how to import the Javascript SDK to your page
December 2017: Custom object sharing is being deprecated. Your best bet from now on is to create another page for that object and have the respective meta tags facebook looks for in there. More info here: developers.facebook.com/docs/sharing/reference/share-dialog
I'm trying to figure out how to do something, and I've tried searching Stack Overflow, but I'm honestly not 100% sure what I'm looking for, so I'm not coming up with anything great.
Here is what I need to do:
We have an app, and you're supposed to like the page to see the app. Great that works.
The client wants us to put a facebook share button on the site, so that when you're finished using the app, you can click the "Share" button and post something to your wall saying, "I just used XXX and you should too!" or whatever. The problem is that the Share button is deprecated. Everything on the facebook developer site says I need to use the like button, but, since you've already LIKED the page to get in, you're going to see that you've already liked the page and not be allowed to click it again to share content on your news feed.
It seems like I'm missing something here. Can you have a like button for a page AND a specific app inside that fan page? It doesn't seem like I can do that. Is what I'm asking even possible?
Yes, you can use the Javascript SDK to post to the wall... this uses jQuery to detect a click on an id which is the share button so make sure you add this before any facebook javascript:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
You will also need to load the FB Javascript SDK if you haven't already:
<script>
window.fbAsyncInit = function () {
FB.init({
appId: 'INSERT APP ID',
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
oauth: true // enable OAuth 2.0
});
};
// 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 add the following code:
$("#shareclick").click(function () {
FB.ui({
method: 'feed',
name: 'The Post Title',
caption: 'skruffymedia testing caption post',
description: (
'Testing the description of the skruffymedia app post!'),
link: 'http://www.skruffymedia.com',
picture: 'http://www.skruffymedia.com/facebook.jpg'
}, function (response) {
if (response && response.post_id) {
alert('posted');
} else {
alert('not shared');
}
});
}); //End Share Click
I'll be including this answer on the next step of my blog
http://www.skruffymedia.com/blog/creating-a-facebook-like-gate-competition/
It is now against Facebook's policies to gate an app or content within an app based on if someone has liked your page.
See the announcement here: https://developers.facebook.com/blog/post/2014/08/07/Graph-API-v2.1/
I have a page tab app with an invite button (aka FB.ui -> apprequests), which when it's run from example.com/pagetab works fine (ie, it pops up a FB.ui friend selector windows etc.) But when I point my app's pagetab to there and load it as an iframe from within Facebook, nothing happens. At first I thought it was a problem with the button not being linked because of jquery not knowing which document was ready but I switched to using onclick and even typing in the command from the Chrome console (in the iframe's scope, of course) but nothing happens... Is this a bug or am I missing something?
Minimal code:
window.fbAsyncInit = function() {
FB.init({
appId : '123456789', // App ID
channelUrl : '//fbjscache.php', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
}); };
(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));
function sendInvite() {
console.log("Inviting...");
FB.ui({method: 'apprequests',
title: 'Check out this great app!',
message: 'Join the fun!',
}, inviteCallback);
}
Then on the page
<div class="facebookButton">Invite</div>
This code works exactly as expected (pops up the cute friend selector dialog) when the page is loaded directly and does nothing when loaded from an iframe. Is this a bug or is there some hidden setting/JS quirk that I'm not catching on to?
After discovering a related question, ( Send dialog doesn't work in page tab ) I realized that the problem is that you need to manually include the parameter display : 'popup' in the options, so the working code requires:
function sendInvite() {
FB.ui({method: 'apprequests',
title: 'Check out this great app!',
message: 'Join the fun!',
display: 'popup'
}, inviteCallback);
}
This behavior is expressly against what the docs say is supposed to happen:
Platform Dialogs are all built to seamlessly run in a variety of display contexts on both the web and mobile web. If you're invoking a Dialog using the JS, iOS or Android SDKs, the display mode will be automatically chosen for you based on the platform and the device being used by the user.
Unless the automatic choice is "no display, with no warning or error message" for the arcane combination of "page tab" and "desktop browser."
For the record, proper canvas apps do not have this limitation. I used line-for-line the same code in a full app and everything worked fine.
I am allowing my users to login to my web-app using their Facebook account.
A user is auto-logged in to my website through Facebook if -
They are registered to my site using Facebook
They haven't logged out of my site and ended their session
They are currently signed into Facebook
This is fine, except, there is a pause between the user accessing the homepage and being taken to their dashboard whilst Facebook checks whether they have logged in. Is there a way to show a sort of pre-loader that says "Signing in with Facebook" whilst the transition is made?
I am using the following Facebook javascript -
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'xxxxxxxxx',
status : true,
cookie : true,
xfbml : true,
oauth : true,
});
FB.Event.subscribe('auth.login', function() {
FB.api('/me', function(response) {
window.location='mysite/fb_signin/';
});
});
};
(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>
Thank you.
With the facebook api you are able to check if the user is connected or not before doing to call to FB.api (that is what taking time).
http://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/
This should help
I agree with Marc that you can use the getLoginStatus() to help you determine what they are before you send them to one place or another. However, you said something was slow. So that led me to look at your code, and it appears you're missing the channelUrl in your FB.init() call (see https://developers.facebook.com/docs/reference/javascript/ for more information). without the channelUrl user interaction with the Javascript SDK functions will be sluggish and slow.