Firebase sign In with email link and verify on different device

Viewed 186

I have created a react js web app in which the user needs to sign in. I have used Firebase email passwordless sign in option. On clicking the send link button a email with the link is sent. Now on clicking the link the user is redirected to another page where the user needs to click a button to verify the email id.
This works fine if the user uses the same device to send the link and verify.

But it is not working if the user sends a link from device A and verifies with device B

How to achieve sign-in functionality with multiple devices.

  1. Link send from device A
  2. Verify from device B
  3. Refresh the page in device A and auto sign-in.

Send the email link and Verify account are in 2 different files to continue the flow

Email.js

import React, {useEffect, useState} from 'react'
import Modal from "react-modal";
import {Fade, Zoom} from "react-reveal";

import {sendemail} from "../../../backend/FirebaseEmail";

function Email() {

    const [email, setEmail] = useState('')
    const [sendingEmail, setSendingEmail] = useState(false)
    const [emailSent, setEmailSent] = useState(false)

    const customStyles = {
        content: {
            top: "50%",
            left: "50%",
            right: "auto",
            bottom: "auto",
            marginRight: "-50%",
            transform: "translate(-50%, -50%)",
            borderRadius: "15px",
            border: "1.2px solid black",
        },
    };

    const sendLink = (event) => {
        setSendingEmail(true)
        event.preventDefault();

        sendemail(email).then((value) => {
            setSendingEmail(true)
            setEmailSent(true)
        }).catch((error) => {
            alert(error.message);
        });
    }
    return (
        <div>
            <input type="email" placeholder="Email" value={email} onChange={e => setEmail(e.target.value)}/>
            <button onClick={(e) => sendLink(e)}>{sendingEmail ? (
                <i className="fa fa-spinner fa-spin"></i>) : ('Send link')}</button>
            <Modal isOpen={emailSent} style={customStyles}>
                <Fade>
                    <div className="email_sent_modal">
                        <Zoom><i className="fas fa-check check"></i></Zoom>
                        <h5>A Link has been sent to your E-mail Id.<br/>
                            Please click on the link to <b>verify</b></h5>
                    </div>
                </Fade>
            </Modal>
        </div>
    )
}

export default Email

Sendemail.js

import {auth} from '../../../firebasesetup'

export const sendemail = (email) => {
    return new Promise((resolve, reject) => {

        var actionCodeSettings = {
            url: process.env.REACT_APP_PUBLIC_URL + 'verify',

            handleCodeInApp: true
        };

        if (auth.currentUser === null) {
            auth.sendSignInLinkToEmail(email, actionCodeSettings)
                .then(function () {
                    resolve(true)
                    window.localStorage.setItem('emailForSignIn', email);
                })
                .catch(function (error) {
                    // Some error occurred, you can inspect the code: error.code
                    reject(false)
                    alert(error)
                });
        } else if (auth.currentUser.emailVerified) {
            window.location.replace(process.env.REACT_APP_PUBLIC_URL);
            //console.log(auth.currentUser)
        }
    })
}

verify.js (verification works completely fine only on the same device)

import React, {useState} from 'react'
import Modal from "react-modal";
import {Fade, Zoom} from "react-reveal";


import {auth} from '../../../firebasesetup'


function Verify() {
    const [isVerifying, setisVerifying] = useState(false)
    const [isverified, setisverified] = useState(false)

    const customStyles = {
        content: {
            top: "50%",
            left: "50%",
            right: "auto",
            bottom: "auto",
            marginRight: "-50%",
            transform: "translate(-50%, -50%)",
            borderRadius: "15px",
            border: "1.2px solid black",
        },
    };

    const verify = () => {
        setisVerifying(true)
        if (auth.isSignInWithEmailLink(window.location.href)) {
            var email = window.localStorage.getItem('emailForSignIn');
            if (!email) {
                email = window.prompt('Please provide your email for confirmation');
            }

            auth.signInWithEmailLink(email, window.location.href)
                .then(function (result) {
                    var user = auth.currentUser;

                    user.updateProfile({
                        displayName: email
                    }).then(function () {
                        setisverified(true)
                    }).catch(function (error) {
                        alert(error)
                    });
                    window.localStorage.removeItem('emailForSignIn');
                })
                .catch(function (error) {
                    alert(error)
                });
        }
    }
    const close = () => {
        window.location.replace(process.env.REACT_APP_PUBLIC_URL);
    }
    return (
        <div>
            <button onClick={verify}>
                {isVerifying ? (
                    <i className="fa fa-spinner fa-spin"></i>) : ('Click to verify')}</button>
            <Modal isOpen={isverified} style={customStyles}>
                <Fade>
                    <div className="email_sent_modal">
                        <Zoom><i className="fas fa-check check"></i></Zoom>
                        <h5>Your account is successfully verified</h5>
                        <button style={{borderRadius: "10px"}} onClick={close}>
                            Done
                        </button>
                    </div>
                </Fade>
            </Modal>
        </div>
    )
}

export default Verify
0 Answers
Related