Facebook Social Plugins comments section hidden by classname (ReactJS) - facebook

I'm using ReactJS (developped by Facebook) and I'm currently having issues displaying a Comment secton from Facebook Social Plugins... kind of ironic but hey, they haven't made a plugins themselft for react.
Anyway, I have inserted the diffent element in my code to add the comment section. When I'm loading the page, I can see the section is loading! (for less than a second) but it desappear quite rapidly. I checked the code generated by facebook and I found that it was adding in the class of my element : FB_hide_iframes. I tried removing it and the section was showing in my page!
The problem is that I don't know how to control the class added to my component.
As you can see, the comments section is present, but it is hidden by the class FB_hide_iframes which i haven't put there.
Here's the code to add the section in my home page (home.js)
componentDidMount() {
...
window.fbAsyncInit = function () {
FB.init({
appId: 'XXXXXXXXXXXXXX',
xfbml: true,
version: 'v2.6'
});
};
(function (d, s, id) {
console.log('test');
const fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
const js = d.createElement(s); js.id = id;
js.src = '//connect.facebook.net/fr_CA/sdk.js#xfbml=1&version=v2.6&appId=XXXXXXXX';
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
FB.XFBML.parse();
...
}
and in the render function I added :
render() {
<div id="fb-root"></div>
...
<div className="fb-comments"
data-href="MY-URL"
data-width="1000"
data-numposts="10"
data-order-by="reverse_time">
</div>
Anyone got an idea?
Edit:
The comments section is showing, but when I go in another section of my website and comeback (Single-page App), it Disappears.
Here's the code of my component :
import React, { Component, PropTypes } from 'react';
import { mediaQueries } from '../../decorators';
#mediaQueries
export default class FacebookComments extends Component {
static propTypes = {
mediaQueries: PropTypes.func.isRequired,
appId: PropTypes.string.isRequired,
version: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
};
state = {
mobile: false,
}
componentDidMount() {
this.props.mediaQueries('(max-width: 950px)', () => {
this.setState({
mobile: true,
});
});
this.props.mediaQueries('(min-width: 951px)', () => {
this.setState({
mobile: false,
});
});
FB.init({
appId: 'XXXXXXXXXXXXXXXXX',
xfbml: true,
version: 'v2.6',
});
(function (d, s, id) {
const fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
const js = d.createElement(s); js.id = id;
js.src = '//connect.facebook.net/fr_CA/sdk.js';
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
}
componentDidUpate() {
FB.XFBML.parse();
}
render() {
const componentWidth = this.state.mobile ? '95%' : '75%';
return (
<div style={{ width: componentWidth }}>
<div id="fb-root"></div>
<div className="fb-comments"
data-href={this.props.url}
data-width="100%"
data-numposts="10"
data-order-by="reverse_time">
</div>
</div>
);
}
}
luschn I don't know and don't understand what you are saying. I put a console.log in fbAsyncInit and it never showed, which mean it never get called. I looked online and there's no information about it. People online only say : Put that in you code and let the magic happen.....
That's why I removed it from my code.
Edit #2 : All I have for Facebook Social Plugin is in this code.

Side Note: It is a terrible idea to add the JS SDK init code in componentDidMount. Instead, add that code to your base HTML or put it in a separate "init" function and make sure it´s loaded before using the component.
Either way, you can only use FB.XFBML.parse after FB.init - that is, when the JS SDK is loaded and initialized:
FB.init({
appId: 'XXXXXXXXXXXXXX',
xfbml: true,
version: 'v2.6'
});
FB.XFBML.parse();
You should even have a warning or error in the browser onsole that FB is not defined with your current code.
You may also need to call FB.XFBML.parse() again in componentDidUpdate.
That being said, here´s my idea of it:
componentDidMount() {
window.fbAsyncInit = () => {
FB.init({
appId: 'xxx',
xfbml: true,
version: 'v2.6'
});
FB.XFBML.parse();
console.log('make sure this happens');
};
(function(d, s, id){
let 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'));
}
componentDidUpdate() {
FB.XFBML.parse();
}
Again, you should put that init/loading stuff elsewhere, but that´s just for optimization. Check your browser console for errors, it may be possible that componentDidUpdate gets called before the JS SDK is initialized. In that case, you may need to check if FB is available:
componentDidUpdate() {
if (FB) {
FB.XFBML.parse();
}
}
Alternatively, you could use a state variable ("isSDKInitialized", for example) and set it to true after FB.init:
componentDidUpdate() {
if (this.state.isSDKInitialized) {
FB.XFBML.parse();
}
}
That´s the minimum you need, the problem with routing is that both componentDidUpdate and componentDidMount will not get called. Try with componentWillReceiveProps in addition (same code as in componentDidUpdate to refresh the Social Plugins).
Check out those links for more information - assuming you are using react-router:
https://github.com/reactjs/react-router/issues/527
https://github.com/reactjs/react-router/blob/master/docs/guides/ComponentLifecycle.md

For those wondering how to correct the bug. You must NOT have : <script src="//connect.facebook.net/fr_CA/sdk.js"></script>
in your <head>, you MUST have <div id="fb-root"></div> at the beginning of the <body> and this code in your FacebookComments Component :
componentDidMount() {
this.props.mediaQueries('(max-width: 950px)', () => {
this.setState({
mobile: true
});
});
this.props.mediaQueries('(min-width: 951px)', () => {
this.setState({
mobile: false
});
});
window.fbAsyncInit = () => {
FB.init({
appId: this.props.appId,
xfbml: true,
version: this.props.version,
});
FB.XFBML.parse();
};
(function (d, s, id) {
const fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {
return;
}
const js = d.createElement(s); js.id = id;
js.async = true;
js.src = '//connect.facebook.net/fr_CA/sdk.js';
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
}
componentWillReceiveProps() {
if (FB) {
console.log('its in receiveProps');
FB.XFBML.parse();
}
}
componentDidUpate() {
if (FB) {
FB.XFBML.parse();
}
}
This me code however is giving me one error, but it doesn't stop the webapp from loading the comments section. You propably will get a :
Unhandled promise rejection ReferenceError: FB is not defined(…)
I tried to make a flag with a element of the state, but it isnt the same state from before.

Related

Facebook Page plugin not loading in Vue Js

I have integrated Facebook Page plugin in my Vuejs app. When I move from one component to another and return back to the component containing the Facebook Page, the page aint loading. It is loading only for the first time and every time I load the complete site. Any solution ?
Found the answer after some digging.
I needed to explicitly load the script every time the component was mounted.
Used this NPM package [ https://www.npmjs.com/package/vue-plugin-load-script ]
mounted() {
this.$loadScript(
"https://connect.facebook.net/en_GB/sdk.js#xfbml=1&version=v5.0&appId=***&autoLogAppEvents=1"
)
.then(() => {
this.$nextTick(() => {
window.FB.XFBML.parse();
});
})
.catch(() => {
console.log("SCRIPT LAODING ERROR");
});
}
You can get FB to parse with vue router like this:
mounted() {
if (typeof FB === "undefined") {
this.fbInit();
} else {
window.FB.XFBML.parse();
}
}
methods() {
fbInit() {
window.fbAsyncInit = function() {
FB.init({
appId: "11111111111",
autoLogAppEvents: true,
xfbml: true,
version: "v6.0"
});
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/fi_FI/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
})(document, "script", "facebook-jssdk");
},
}

How to use Facebook SDK with Nuxt.js?

You can see my code.
npm install vue init nuxt/koa my-project (koa#2)
pages
|- login.vue
<script>
export default {
name: 'login',
method: {
login () {
let vm = this
FB.login(function (response) {
vm.statusChangeCallback(response)
}, {scope: 'publish_actions'})
}
},
mounted () {
console.log('mounted')
let vm = this
window.fbAsyncInit = () => {
FB.init({
appId: 'my-facebook-app-id',
cookie: true,
xfbml: true,
version: 'v2.8'
})
FB.getLoginStatus(function (response) {
vm.statusChangeCallback(response)
})
}
(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>
but,
sdk.js:96 Uncaught TypeError: vm.statusChangeCallback is not a function
When using the Nuxt project (nuxt/koa), what is the best way to use the Facebook SDK?
I running into the same problem this day. Here is my solution with nuxt.js
First create a plugin plugins/fb-sdk.js
const vue_fb = {}
vue_fb.install = function install(Vue, options) {
(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)
console.log('setting fb sdk')
}(document, 'script', 'facebook-jssdk'))
window.fbAsyncInit = function onSDKInit() {
FB.init(options)
FB.AppEvents.logPageView()
Vue.FB = FB
window.dispatchEvent(new Event('fb-sdk-ready'))
}
Vue.FB = undefined
}
import Vue from 'vue'
Vue.use(vue_fb, {
appId: 'your-app-id',
autoLogAppEvents: true,
xfbml: true,
version: 'v2.9'
})
We can use Vue.FB to invoke methods in FB SDK and listen to the fb-sdk-ready event in any component like this:
export default{
data: function () {
return {isFBReady: false}
},
mounted: function () {
this.isFBReady = Vue.FB != undefined
window.addEventListener('fb-sdk-ready', this.onFBReady)
},
beforeDestroy: function () {
window.removeEventListener('fb-sdk-ready', this.onFBReady)
},
methods: {
onFBReady: function () {
this.isFBReady = true
}
}
}
First create a javascript file and include it in your static/js folder:
static/js/fb-sdk.js
include the script below in your fb-sdk.js file:
window.fbAsyncInit = function () {
FB.init({
appId: '<insert your app id>',
autoLogAppEvents: true,
xfbml: true,
version: 'v2.10'
})
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 = 'https://connect.facebook.net/en_US/sdk.js'
fjs.parentNode.insertBefore(js, fjs)
}(document, 'script', 'facebook-jssdk'))
Finally in your nuxt.config.js, include the script at the header section:
module.exports = {
head: {
title: 'myTitle',
meta: [
{ charset: 'utf-8' }
],
script: [
{ src: '/js/fb-sdk.js' }
]
}
}
You can now use window.FB to execute methods available in FB SDK in your components.
I used [combined inject][1] to insert the plugin in the context (thus making it accessible in the store):
In plugins/fb-sdk.js:
const vue_fb = {}
vue_fb.install = function install(Vue, options) {
(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)
console.log('setting fb sdk')
}(document, 'script', 'facebook-jssdk'))
window.fbAsyncInit = function onSDKInit() {
FB.init(options)
FB.AppEvents.logPageView()
Vue.FB = FB
window.dispatchEvent(new Event('fb-sdk-ready'))
vue_fb.sdk = FB // do not forget this line
}
Vue.FB = undefined
}
import Vue from 'vue'
Vue.use(vue_fb, {
appId: 'your-app-id',
autoLogAppEvents: true,
xfbml: true,
version: 'v2.9'
})
// and this line
export default ({ app }, inject) => {
inject('fb', vue_fb)
}
Making it accessible through this.$fb
[1]: https://nuxtjs.org/guide/plugins/
A plugin is a good way to inject some feature related logic into Vue instance but, I don't think your Vue instance has to have Facebook login logic all the time. I'd rather go with a login-with-facebook-button component like the following fashion;
<template>
<v-btn v-if="facebookSdkReady" color="primary" dark type="button" #click="login">
<v-layout mr-2>
<v-icon name="brands/facebook"/>
</v-layout>Login with Facebook
</v-btn>
</template>
<script>
export default {
name: 'LoginWithFacebook',
data() {
return {
facebookSdkReady: false
}
},
mounted() {
const installFacebookSdkScript = (d, s, id) => {
if (d.getElementById(id)) {
this.facebookSdkReady = true
return
}
let fjs = d.getElementsByTagName(s)[0]
let js = d.createElement(s)
js.id = id
js.src = 'https://connect.facebook.net/en_US/sdk.js'
fjs.parentNode.insertBefore(js, fjs)
}
installFacebookSdkScript(document, 'script', 'facebook-jssdk')
window.fbAsyncInit = () => {
FB.init({
appId: '16653216336xxxxx',
cookie: true,
xfbml: true,
version: 'v3.2'
})
FB.AppEvents.logPageView()
this.facebookSdkReady = true
}
},
methods: {
// just a sample code copied from my code base.
// here, you can replace this with your own.
async login() {
const url = await this.$store.dispatch('auth/fetchSocialLoginUrl', {
provider: 'facebook'
})
window.location.href = url
}
}
}
</script>
you can just use nuxt-auth it very easy
after install it add to your nuxt-config
auth: {
redirect: {
login: '/login',
logout: '/',
callback: '/callback',
home: '/'
},
strategies: {
facebook: {
endpoints: {
userInfo: 'https://graph.facebook.com/v6.0/me?fields=id,name,picture{url}',
},
callback: '/callback',
clientId: 'YOUR_APP_CLIENT_ID',
scope: ['public_profile', 'email'],
},
},
then create callback compountent if it needed in your callback compountent you can access facebook data from this.$route.query;

Facebook pagetab error 500

I have created a Facebook Page Tab. Everything works as expected, the tab can be added to a user's page, they see an Add Page Tab Dialog, etc.
It doesn't work however, when someone is currently "Using Facebook as" a page that they manage. Looking at Chrome developer tools I see an HTTP 500 internal server error.
To recreate this:
<script>
window.fbAsyncInit = function () {
FB.init({
appId: 'XXXXXXXXXXXXXXXX',
xfbml: true,
version: 'v2.0',
cookie: 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/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
function init() {
console.log("go!");
FB.ui({
method: 'pagetab',
redirect_uri: 'https://www.somedomain.com/widget/?id=3280',
});
}
setTimeout(function () {
init();
}, 2000);
</script>
I'm at a complete loss, any suggestions are greatly welcomed.

Post feed with js sdk to pagewall

Im trying to send posts to a wall of a page im an admin to through the js sdk. I have made it do i can do it for myself(my personal user) but i cannot get it to work as the "page".
<div id="fb-root"></div>
<script type="text/javascript">
function SendToFacebook()
{
window.fbAsyncInit = function () {
// init the FB JS SDK
FB.init({
appId: '**CORRECT ID**', // App ID from the app dashboard
channelUrl: '**MYPAGE**/channel.html', // Channel file for x-domain comms
status: false, // Check Facebook Login status
xfbml: true // Look for social plugins on the page
});
FB.ui(
{
method: 'feed',
name: 'MyFeed',
link: '',
// picture: '',
caption: 'My caption',
description: 'test',
message: 'MESSAGE?',
},
function (response) {
if (response && response.post_id) {
alert('Delat på facebook.');
} else {
alert('Inte delat på facebook.');
}
}
);
// 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>
This posts to my own user page, and ive tried the "to" parameter but it send the post from my personal user to the page. Is there any way to make this though the login function?
bare in mind that im fairly new to this so demos and examples are welcome.
I got it to work after a hard days work, if any1 is interested heres how i did.
<script type="text/javascript">
function SendToFacebook()
{
window.fbAsyncInit = function () {
// init the FB JS SDK
FB.init({
appId: '***', // App ID from the app dashboard
channelUrl: '***', // Channel file for x-domain comms
status: false, // Check Facebook Login status
xfbml: true // Look for social plugins on the page
});
FB.login(function (response) {
FB.api('/me/accounts', function (apiresponse) {
var data = {
message: "mymessage",
display: 'iframe',
caption: "caption",
name: "name",
description: "description",
to: **wallid**,
from: **wallid**
};
FB.api('/**wallid**/feed', 'post', data, function () {
console.log(arguments);
});
});
}, { scope: 'manage_pages' });
};
// 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>
I found this solution and I tried it, although I dont know how it was 3 years ago, now you need to append page access token you receive via /me/accounts calling (also you must be admin of that page etc.) so todays working solution could look like this:
FB.api('/me/accounts', function (apiresponse) {
console.log(apiresponse);
var data = {
message: "mymessage",
//display: 'iframe',
caption: "caption",
picture: 'www.bla.com/image.jpg',
link: 'www.facebook.com',
name: "name",
description: "description",
to: **APP IP**,
from: **APP IP**,
access_token: apiresponse.data[0].access_token
};
FB.api('/**APP IP**/feed', 'post', data, function () {
console.log(arguments);
});
});

Access denied while redirecting back to application

This is my implementation of facebook login functionality using Facebook SDK.
<script type="text/javascript">
window.fbAsyncInit = function () {
// Initialize the SDK upon load
FB.init({
appId: '1xxxxxxxxxxxx', // App ID
channelUrl: '//' + window.location.hostname + '//Home/Index',
scope: 'id,name,gender,user_birthday,email,first_name,last_name,access_token',
status: true,
cookie: true,
xfbml: true
});
// listen for and handle auth.statusChange events
FB.Event.subscribe('auth.statusChange', OnLogin);
};
// This method will be called after the user login into facebook.
function OnLogin(response) {
if (response.authResponse) {
var access_token = FB.getAuthResponse()['accessToken'];
$('#AccessToken').attr('value', access_token);
$("#AuthenticatedWithFacebook").attr("value", true);
FB.api('/me', LoadValues);
}
else {
$("#AuthenticationToken").removeAttr('value');
$("#AuthenticatedWithFacebook").attr("value", false);
}
}
//This method will load the values to the labels
function LoadValues(me) {
if (me.id) {
$("#UserId").attr("value", me.id);
$("#AuthenticationToken").attr("value", "facebook/" + me.id);
$("#FirstName").attr("value", me.first_name);
$("#LastName").attr("value", me.last_name);
$("#EmailAddress").attr("value", me.email);
}
}
</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/en_US/all.js#xfbml=1&appId=1xxxxxxxxxxxxxx";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
Login Pop-Up works just fine but after logging in I'm getting following exception:
Exception was thrown at line 38, column 184 in http://static.ak.fbcdn.net/rsrc.php/v2/yQ/r/Yax99g-1J46.js
0x80070005 - JavaScript runtime error: Access is denied.
I'm testing here on localhost (http://localhost:59777/) which I have configured in my Facebook application as well.