Problem: Use FB sdk in react.
Solution: Load FB SDK
- Helper function (to load up the sdk)
- React code
- Node js function
// FBinit.js
const FB_APP_ID='xxxx';
export function initFacebookSdk() {
return new Promise(resolve => {
// wait for facebook sdk to initialize before starting the react app
window.fbAsyncInit = function () {
window.FB.init({
appId: FB_APP_ID,
xfbml: true,
version: 'v14.0'
});
resolve()
};
});
}
export function loadFacebookSDK(d, s, id){
return new Promise(resolve => {
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);
resolve()
})
}
export const FbLogin = () => {
return new Promise( resolve => {
if (typeof window.FB == 'undefined') {
loadFacebookSDK(document, "script", "facebook-jssdk");
initFacebookSdk();}
window.FB.login(response => {
if (response.authResponse) {
resolve(response);
} else {
resolve(response);
}
}, {
scope: 'public_profile,email',
enable_profile_selector: true,
auth_type: 'rerequest',
return_scopes: true
});
})
}
export const FbSignup = () => {
return new Promise( resolve => {
if (typeof window.FB == 'undefined') {
loadFacebookSDK(document, "script", "facebook-jssdk");
initFacebookSdk();}
window.FB.login(res => {
console.log("FbSignup FB.login",res);
if (res.status === 'connected') {
window.FB.api('/me', {fields: 'name,email,picture,birthday'}, (response) => {
if (response.name) {
resolve({res,response});
} else {
resolve({res,response});
}
});
}
}, {scope: 'user_birthday,public_profile,name,email'});
})
}
export function FBlogout() {
let FBstatus = window.FB.getLoginStatus();
console.log("FBstatus",FBstatus);
if (FBstatus.status === 'connected') {
window.FB.logout(function(response) {
console.log("fb logout triggered",response);
});
}
}
loadFacebookSDK(document, "script", "facebook-jssdk");
initFacebookSdk();
Login.js
import { FacebookLoginButton } from "react-social-login-buttons";
import * as FBinit from '../../../utils/fbintit';
class LoginPage extends Component {
constructor(props) {
super(props);
this.state = {
userId: "",
password: "",
};
this.loginFB = this.loginFB.bind(this);
}
render() {
return (
<div>
{" "}
<FacebookLoginButton
align={"center"}
onClick={(e) => this.loginFB(e)}
>
<span>Sign in with Facebook</span>
</FacebookLoginButton>
</div>
);
}
async loginFB(e){
e.preventDefault();
// console.log("loginFB");
const data = await FBinit.FbLogin();
// console.log("FBinit.FbLogin",data);
if(data.authResponse==null){
return;
}
this.props.dispatch(UserActions.fblogin({accessToken:data.authResponse.accessToken,userID:data.authResponse.userID}, response => {
console.log("fb LOGIN_RESPONSE", response);
if (response.status) {
if(response.data.dob=="1000-12-01"){
this.props.history.push('/birthday-wall');
return;
}
this.props.history.push('/');
} else {
let error = response.data.message
? response.data.message
: "Something went wrong, try again later!";
}
}))
}
}
SignUp.js
import { FacebookLoginButton } from "react-social-login-buttons";
import * as FBinit from '../../../utils/fbintit';
class SignupPage extends Component {
constructor(props) {
super(props);
this.state = {
userId: "",
password: "",
};
this.signupFB = this.signupFB.bind(this);
}
render() {
return (
<div>
{" "}
<FacebookLoginButton
align={"center"}
onClick={(e) => this.signupFB(e)}
>
<span>Sign in with Google</span>
</FacebookLoginButton>
</div>
);
}
async signupFB(e){
console.log("signupFB");
e.preventDefault();
const data = await FBinit.FbLogin();
// console.log("FBinit.FbLogin",data);
if(data.authResponse==null){
return;
}
this.props.dispatch(UserActions.FBsignup({accessToken:data.authResponse.accessToken,userID:data.authResponse.userID}, response => {
if (response.status) {
if(response.data.dob=="1000-12-01"){
this.props.history.push('/birthday-wall');
return;
}
this.props.history.push('/');
} else {
let error = response.data.message
? response.data.message
: "Something went wrong, try again later!";
}
}))}
}
node.js
var mongoose = require("mongoose"),
Customer = mongoose.model("Customer"),
SocialLogin = Helpers.socialLogin;
const moment = require("moment");
var FBCustomerLogin = async function (req, res, next) {
var customer = req.body;
const {
userID,
accessToken,
} = customer;
let fbUrl = `https://graph.facebook.com/${userID}?fields=id,name,email&access_token=${accessToken}`;
let fbAPiData = await SocialLogin.axiosGet(fbUrl);
const {
email
} = fbAPiData;
let result = Customer.findOne({
email: email
})
.then(function (user) {
try {
var Guser = user.restrict();
return res.status(200).json({
user: Guser,
token: jwt.signJwt(Guser)
});
} catch (e) {
return res.status(400).json({
message: "User not found, Please Signup!",
error: e,
status: 400
});
}
})
};
var signUPFBCustomer = endPointHandler(async function (req) {
var customer = req.body;
const {
userID,
accessToken
} = customer;
let fbUrl = `https://graph.facebook.com/${userID}?fields=name,email,birthday,age_range&access_token=${accessToken}`;
let fbAPiData = await SocialLogin.axiosGet(fbUrl);
const {
name,
email,
birthday
} = fbAPiData;
const neededKeys = ['name', 'email','birthday'];
let fbcustomer = {};
if(!neededKeys.every(key => Object.keys(fbAPiData).includes(key))){
let keys = Object.keys(fbAPiData);
let difference = neededKeys.filter(x => !keys.includes(x)).toString();
if(difference=='birthday'){
fbcustomer.email = email;
fbcustomer.name = {
first: name,
last: ""
};
fbcustomer.password = Math.random().toString(36).slice(2, 10);
fbcustomer.dob = `1000-12-01`;
fbcustomer.isEmailVerified = true;
return stripe.createCustomer(fbcustomer)
.then(result => {
fbcustomer.stripeID = result.id
return Customer.create(fbcustomer)
.then(async function (user) {
return user;
})
.then(function (u) {
return Customer.findOne({
_id: u._id
})
}) // We need a Customer instance for the then statement of tokenize to work. generateVeirficationEmail restricts the returned user and is not an instane of the Customer model.
.then(Customer.tokenize);
});
}
throw {
status: 403,
message: `Unable to read ${difference}`
};
}
var birthdayFormated = moment(birthday, 'MM/DD/YYYY').format('YYYY-MM-DD');
const age = moment().diff(birthdayFormated, 'years');
const isLegal = (age >= 21);
if (!isLegal) {
throw {
status: 403,
message: "User is not over the age of 21 or Invalid Birthdate"
};
}
fbcustomer.email = email;
fbcustomer.name = {
first: name,
last: ""
};
fbcustomer.password = Math.random().toString(36).slice(2, 10);
fbcustomer.dob = birthdayFormated;
fbcustomer.isEmailVerified = true;
return stripe.createCustomer(fbcustomer)
.then(result => {
fbcustomer.stripeID = result.id
return Customer.create(fbcustomer)
.then(async function (user) {
return user;
})
.then(function (u) {
return Customer.findOne({
_id: u._id
})
}) // We need a Customer instance for the then statement of tokenize to work. generateVeirficationEmail restricts the returned user and is not an instane of the Customer model.
.then(Customer.tokenize);
});
});
Social login helper.js
//Social login
const axios = require('axios');
async function axiosGet(url) {
try {
const {data:response} = await axios.get(url) //use data destructuring to get data from the promise object
return response;
}
catch (error) {
console.log(error);
}
}
module.exports = {
axiosGet
}
Top comments (0)