DEV Community

Sahil kashyap
Sahil kashyap

Posted on

7 4

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

Image of Datadog

The Future of AI, LLMs, and Observability on Google Cloud

Datadog sat down with Google’s Director of AI to discuss the current and future states of AI, ML, and LLMs on Google Cloud. Discover 7 key insights for technical leaders, covering everything from upskilling teams to observability best practices

Learn More

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more