DEV Community

Sahil kashyap
Sahil kashyap

Posted on

Facebook Login React Js Node.js

Problem: Use FB sdk in react.
Solution: Load FB SDK

  1. Helper function (to load up the sdk)
  2. React code
  3. 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();
Enter fullscreen mode Exit fullscreen mode

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!";


      }


    }))
  }

}
Enter fullscreen mode Exit fullscreen mode

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!";


      }


    }))}
}

Enter fullscreen mode Exit fullscreen mode

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);
    });


});

Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

Discussion (0)