Closed
Description
[REQUIRED] Describe your environment
- Operating System version: MacOS Monterey 12.3
- Browser version: Chrome version 100.0.4896.75
- Firebase SDK version: 9.6.10
- Firebase Product: auth
[REQUIRED] Describe the problem
When I use the RecaptchaVerifier on my site with AppCheck enabled, I get an error when I call the verify method on the RecaptchaVerifier. The error is as follows:TypeError: this.getAssertedRecaptcha(...).render is not a function
This only happens when AppCheck is enabled; without AppCheck it behaves normally, that is, the verification goes through. Also, it doesn't happen in development or production when running at localhost with the emulator. Only occurs in the deployed code in firebase hosting.
Steps to reproduce:
- Create a react app with firebase app check enabled
- Create a simple page with an invisible RecaptchaVerifier and a button that when clicked calls 'RecaptchaVerifier.verify()'
- Build the app and deploy to hosting
- Notice the error occurs when you press the button that calls the verify function
Relevant Code:
In my root App.tsx file, appcheck is initialized this way
if(!getApps().length){constapp=initializeApp(firebaseConfig)// console.log(`Initializing app check with ${import.meta.env.VITE_RECAPTCHA_KEY}`)//if localhost set debug app check token//https://firebase.google.com/docs/app-check/web/debug-provider?authuser=0&hl=enif(window.location.hostname==="localhost"){//this must be set to true to generate a new token and once generated and registered, we need to set the token value in env//(self as any).FIREBASE_APPCHECK_DEBUG_TOKEN = true(window.selfasany).FIREBASE_APPCHECK_DEBUG_TOKEN=import.meta.env.VITE_APP_CHECK_DEBUG_TOKEN}initializeAppCheck(app,{provider: newReCaptchaEnterpriseProvider(import.meta.env.VITE_RECAPTCHA_KEY),isTokenAutoRefreshEnabled: true})}
The RecaptchaVerifier component is as follows
exportconstFirebaseRecaptcha=({instructionMessage, onVerificationComplete}: FirebaseRecaptchaProps)=>{const[isCaptchaLoading,setCaptchaLoading]=useState(false)const[verificationErrored,setVerificationErrored]=useState(false)letverifier: any=nulluseEffect(()=>{console.log("Initializing captcha");verifier=newRecaptchaVerifier("recaptcha-container",{'size': 'invisible','callback': function(response: any){console.log("verification success")setCaptchaLoading(false)onVerificationComplete(CaptchaVerificationStatus.SUCCESS)}},getAuth())},[])constonStartClick=async()=>{if(verifier){try{setCaptchaLoading(true)console.log("About to verify")constres=awaitverifier.verify()}catch(e){setCaptchaLoading(false)console.error(e)onVerificationComplete(CaptchaVerificationStatus.FAIL)}}}// <Button variant="contained" color="primary" id={recaptchaButtonId} onClick={()=>onStartClick()} className={`${classes.actionButton} ${classes.bottomMargin}`}>// Start// </Button>return(<><divid="recaptcha-container"></div><Typographyvariant="h6"gutterBottomsx={{mb: 2}}>{instructionMessage ? instructionMessage : getStrings().message_start_page}</Typography>{isCaptchaLoading ? <CircularProgresssx={{mb: 2}}/>:<Buttonvariant="contained"color="primary"onClick={()=>onStartClick()}sx={{mb: 2,width: '50%'}}>{getStrings().button_start}</Button>}</>)}