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)