Create a Picture Competition Website in Express JS, MEVN

Login with Facebook

We can also add functionality that allows users to log in with their Facebook account. First, you need to go to the Facebook developers page and create a new app. After that, put the following lines in your “footer.ejs” file:

<div id="fb-root"></div>
<script async defer crossorigin="anonymous" src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v12.0&appId={your_app_id}&autoLogAppEvents=1" nonce="1EaAEm3K"></script>

Make sure to replace “{your_app_id}” with your Facebook app ID. Then we need to render the Facebook login button. So go to “login.ejs” and put the following code in the [facebook login button] section:

<div class="col-md-6">
	<div class="fb-login-button" data-width="" data-size="large" data-button-type="continue_with" data-layout="default" data-auto-logout-link="false" data-use-continue-as="false" data-onlogin="onFacebookLogin"></div>
</div>

And in your Javascript code, we need to create a function that will display the login pop-up by Facebook and will authenticate the user from server side too.

function onFacebookLogin(data) {
	console.log(data);

	var userID = data.authResponse.userID;

	// make the API call
	FB.api(
	    "/" + userID + "/?fields=id,name,email,picture.height(2048)",
	    "GET",
	    {},
	    function (response) {
			if (response && !response.error) {
				//handle the result
				console.log(response);

				var id = response.id;
				var name = response.name
				var email = response.email;
				var picture = response.picture.data.url;

				var formData = new FormData();
				formData.append("id", id);
				formData.append("name", name);
				formData.append("email", email);
				formData.append("picture", picture);

				myApp.callAjax(mainURL + "/facebookLogin", formData, function (response) {
		            // convert the JSON string into Javascript object
		            var response = JSON.parse(response);
		            console.log(response);

		            // if the user is created, then redirect to login
		            if (response.status == "success") {
		            	// get access token from server
		                var accessToken = response.accessToken;

		                // save in local storage
		                localStorage.setItem(accessTokenKey, accessToken);

		                // redirect to home page
		                window.location.href = "/";
		            } else {
		            	swal("Error", response.message, "error");
		            }
				});
			}
	    }
	);
}

Now we need to create a POST route “facebookLogin” in our “server.js” file that will create the user if not exist. Otherwise, it will simply update the user’s document and add Facebook profile information in it.

app.post("/facebookLogin", async function (request, result) {
	const id = request.fields.id;
	const name = request.fields.name;
	const email = request.fields.email;
	const picture = request.fields.picture;

	// check if email already exists
    var user = await db.collection("users").findOne({
        "email": email
    });

    if (user == null) {
    	// insert in database
        await db.collection("users").insertOne({
            "name": name,
            "email": email,
            "password": "",
            "picture": picture,
            "accessToken": "",
            "notifications": [],
            "bio": "",
            "dob": "",
            "country": "",
            "phone": "",
            "website": "",
            "twitter": "",
            "facebook": "",
            "googlePlus": "",
            "linkedIn": "",
            "instagram": "",
            "resetToken": "",
            "isVerified": true,
            "verificationToken": "",
            "createdAt": new Date().getTime()
        });
    }

    // generate JWT of user
    var accessToken = jwt.sign({
        "email": email
    }, accessTokenSecret);

    // update JWT of user in database
    await db.collection("users").findOneAndUpdate({
        "email": email
    }, {
        $set: {
            "accessToken": accessToken,
            "facebookData": {
            	"id": id,
            	"name": name,
            	"email": email,
            	"picture": picture
            }
        }
    });

	result.json({
        "status": "success",
        "message": "Login successfully",
        "accessToken": accessToken
    });
});

Now your users will also be able to log in with their Facebook account as well.