t49tran / react-google-recaptcha-v3

Google Recaptcha V3 integration for React
MIT License
434 stars 91 forks source link

executeRecaptcha never resolve #81

Closed Kif11 closed 3 years ago

Kif11 commented 3 years ago

If recaptcha token is not specified executeRecaptcha() promise doesn't resolve or reject. In the example below token or error is never printed.

try {
  const recaptchaToken = await executeRecaptcha('signup_modal');
  console.log('token', recaptchaToken);
} catch (error) {
  console.log(error)
}

This behavior can be described by the following example code.

const simple = async () => {
  console.log('start')
  await new Promise(resolve => {})
  console.log('done.')
}

I'm using "react-google-recaptcha-v3": "^1.7.1"

t49tran commented 3 years ago

@Kif11, what the exact version you are using ? What is the version in your yarn.lock or package-lock.json ?

Kif11 commented 3 years ago

@t49tran

cat yarn.lock | grep capt
react-google-recaptcha-v3@^1.7.1:
  resolved "https://registry.yarnpkg.com/react-google-recaptcha-v3/-/react-google-recaptcha-v3-1.7.1.tgz#e49f81e42b59c04ab9b488b88db3dd6e41e7aa00"

One of my teammates verified this behavior on his machine. I didn't take time to set up isolated test though.

t49tran commented 3 years ago

@Kif11, I am not sure what you mean by saying If recaptcha token is not specified ? Also, how do you get access to executeRecaptcha ?

The piece of code you given doesn't provide me with enough information to debug anything ? If it's possible, can you share the code and how you use the GoogleRecaptchaProvider and get access to executeRecaptcha.

t49tran commented 3 years ago

Also, you might want to help a look at this issue https://github.com/t49tran/react-google-recaptcha-v3/issues/56

KarlBaumann commented 3 years ago

executeRecaptcha is undefined for me image

t49tran commented 3 years ago

executeRecaptcha is undefined for me image

The executeRecaptcha function is undefined while the javascript is being loaded, please do a null check an call it only when is it available. For your use case, if you want to trigger it on page load, you can do something like:

const {executeRecaptcha} = useGoogleReCaptcha();

useEffect(() => {
    if (!executeRecaptcha) {
       return;
   }

  const verifyRecaptcha = async() => {
      const recaptchaToken = await executeRecaptcha("login_page");
  };

 verifyRecaptcha();
}, [executeRecaptcha]);

That section in ReadMe.md has not been updated for a while and I will update it soon.

t49tran commented 3 years ago

Doc updated with #84

egolegegit commented 1 year ago

Thanks for answering the question above. This solved my problem too :) ! Here is the code running nextjs, form component in modal window, maybe it will be useful to others:

const { executeRecaptcha } = useGoogleReCaptcha();

    useEffect(() => {
        if (!executeRecaptcha) {
            return;
        }

        const verifyRecaptcha = async () => {
            const recaptchaToken = await executeRecaptcha('order_form');
        };

        verifyRecaptcha();
    }, [executeRecaptcha]);

    const handleSubmitForm = useCallback(
        async (values) => {
            if (!executeRecaptcha) {
                console.log('Execute recaptcha not yet available');
                return;
            }

            const gReCaptchaToken = await executeRecaptcha('OrderForm');
            await submitEnquiryForm(gReCaptchaToken, values);
        },
        [executeRecaptcha],
    );

    const submitEnquiryForm = async (gReCaptchaToken, values) => {
        fetch('/api/captchaEnquiry', {
            method: 'POST',
            headers: {
                Accept: 'application/json, text/plain, */*',
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                data: { ...values },
                gRecaptchaToken: gReCaptchaToken,
            }),
        })
            .then((res) => res.json())
            .then((res) => {
                // console.log(res, 'response from backend');
                if (res?.status === 'success') {
                    setNotification(res?.message);
                    notifications.show({
                        title: res?.message,
                        message: '',
                        icon: <ShieldCheck size="1rem" />,
                        color: 'teal',
                    });
                    close();
                } else {
                    setNotification(res?.message);
                }
            });
    };