I am building a react-native app with expo, I have only 2 components, WelcomeScreen and PhoneLoginScreen. I am trying to implement firebase phone authentication which works fine on the Web but on iOS Simulator I get an error Verifier._reset is not a function. (In 'verifier._reset()', 'verifiier._reset' is undefined
Verifier._reset is not a function. (In 'verifier._reset()', 'verifiier._reset' is undefined
and on Android, it just crashes when I click the continue button that navigates to the PhoneLoginScreen component. Codes below:
App.js
import React from "react"
import { NavigationContainer } from "@react-navigation/native"
import { createNativeStackNavigator } from "@react-navigation/native-stack"
import WelcomeScreen from "./components/WelcomeScreen"
import PhoneLoginScreen from "./components/auth/PhoneLoginScreen"
const Stack = createNativeStackNavigator()
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Welcome">
<Stack.Screen
name="Welcome"
component={WelcomeScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="PhoneLogin"
component={PhoneLoginScreen}
options={{ headerShown: false }}
/>
</Stack.Navigator>
</NavigationContainer>
)
}
WelcomeScreen.js
import React from "react"
import { Text, View, Button } from "react-native"
export default function WelcomeScreen({ navigation }) {
return (
<View
style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Welcome</Text>
<Button
title="Continue"
onPress={() => navigation.navigate("PhoneLogin")}
/>
</View>
)
}
PhoneLoginScreen.js
import React, { useRef, useState } from "react"
import { firebaseApp, auth } from "../../firebase"
import {
Text,
View,
TextInput,
Button,
StyleSheet,
TouchableOpacity,
} from "react-native"
import {
FirebaseRecaptchaVerifierModal,
FirebaseRecaptchaBanner,
} from "expo-firebase-recaptcha"
import { PhoneAuthProvider, signInWithCredential } from "firebase/auth"
export default function PhoneLoginScreen() {
const recaptchaVerifier = useRef(null)
const [message, showMessage] = useState()
const [phoneNumber, setPhoneNumber] = useState()
const [verificationId, setVerificationId] = useState()
const [verificationCode, setVerificationCode] = useState()
const firebaseConfig = firebaseApp ? firebaseApp.options : undefined
const attemptInvisibleVerification = true
return (
<View style={styles.center}>
<FirebaseRecaptchaVerifierModal
ref={recaptchaVerifier}
firebaseConfig={firebaseConfig}
attemptInvisibleVerification={attemptInvisibleVerification}
/>
<Text style={{ marginTop: 20 }}>Enter phone number</Text>
<TextInput
style={{ marginVertical: 10, fontSize: 17 }}
placeholder="+1 999 999 9999"
autoFocus
autoCompleteType="tel"
keyboardType="phone-pad"
textContentType="telephoneNumber"
onChangeText={phoneNumber => setPhoneNumber(phoneNumber)}
/>
<Button
title="Send Verification Code"
disabled={!phoneNumber}
onPress={async () => {
try {
const phoneProvider = new PhoneAuthProvider(auth)
const verificationId =
await phoneProvider.verifyPhoneNumber(
phoneNumber,
recaptchaVerifier.current
)
setVerificationId(verificationId)
showMessage({
text: "Verification code has been sent to your phone.",
})
} catch (err) {
showMessage({
text: `Error 111: ${err.message}`,
color: "red",
})
}
}}
/>
<Text style={{ marginTop: 20 }}>Enter Verification code</Text>
<TextInput
style={{ marginVertical: 10, fontSize: 17 }}
editable={!!verificationId}
placeholder="123456"
onChangeText={setVerificationCode}
/>
<Button
title="Confirm Verification Code"
disabled={!verificationId}
onPress={async () => {
try {
const credential = PhoneAuthProvider.credential(
verificationId,
verificationCode
)
await signInWithCredential(auth, credential)
showMessage({
text: "Phone authentication successful 👍",
})
} catch (err) {
showMessage({
text: `Error: ${err.message}`,
color: "red",
})
}
}}
/>
{message ? (
<TouchableOpacity
style={[
StyleSheet.absoluteFill,
{
backgroundColor: 0xffffffee,
justifyContent: "center",
},
]}
onPress={() => showMessage(undefined)}>
<Text
style={{
color: message.color || "blue",
fontSize: 17,
textAlign: "center",
margin: 20,
}}>
{message.text}
</Text>
</TouchableOpacity>
) : undefined}
{attemptInvisibleVerification && <FirebaseRecaptchaBanner />}
</View>
)
}
const styles = StyleSheet.create({
center: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
})
firebase.js
import firebase from "firebase/compat/app"
import "firebase/compat/auth"
import "firebase/compat/firestore"
// Initialize Firebase
const firebaseConfig = {
// Config info...
}
let firebaseApp
if (firebase.apps.length === 0) {
firebaseApp = firebase.initializeApp(firebaseConfig)
} else {
firebaseApp = firebase.app()
}
const auth = firebase.auth()
export { auth, firebaseApp }
package.json dependencies
"dependencies": {
"@react-navigation/native": "^6.0.6",
"@react-navigation/native-stack": "^6.2.5",
"expo": "~43.0.2",
"expo-firebase-recaptcha": "~2.0.2",
"expo-status-bar": "~1.1.0",
"firebase": "^9.5.0",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",
"react-native-safe-area-context": "3.3.2",
"react-native-screens": "~3.8.0",
"react-native-web": "0.17.1",
"react-native-webview": "11.13.0"
}
I have googled forever and nothing works. Please advice
This is a bug. The maintainers of "expo-firebase-recaptcha" have yet to publish a fix, so until that day comes, this is how you fix it yourself:
Go to node_modules/expo-firebase-recaptcha, open the build
folder and find FirebaseRecaptchaVerifierModal.js
.
Inside of FirebaseRecaptchaVerifierModal, add the following function to the component definition:
_reset = () => {}
I've included a snippet of the file after adding the empty function definition:
FirebaseRecaptchaVerifierModal.js
[...]
else {
this.setState({
visible: true,
visibleLoaded: false,
resolve,
reject,
});
}
});
}
/**
* Add the following line anywhere inside of the FirebaseRecaptchaVerifierModal component.
*/
_reset = () => {}
onVisibleLoad = () => {
this.setState({
visibleLoaded: true,
});
};
[...]
Note: You will have to do this after every yarn/npm installl or change in node_modules until the publishers push an update.
Error: verifier._reset is not a function. when trying to Sign in with phone using firebase, react native and Expo
FirebaseRecaptchaVerifierModal attemptInvisibleVerification Crashes on Android Emulator look at this.This is help me so well
I add
`<FirebaseRecaptchaVerifierModal
ref={recaptchaVerifierRef}
firebaseConfig={firebaseConfig}
androidHardwareAccelerationDisabled
attemptInvisibleVerification />` this line on my FirebaseRecaptchaVerifierModal this gonna help to my to problem.
** FIX FOR EXPO 45, 46 **
After Surfing through the internet for answers, i failed and din't find anything to make it work on Expo 45 and Expo 46, finally took it to my hands because We can't ship an app with manual recaptcha as it is very bad UX. So after trying every possible prop in the FirebaseRecaptchaVerifierModal, I FINALLY FOUND THE WORKING FIX
By Combining all the fixes and adding one of my own found, I finally can rest in peace as this is now working
// Declare the Timeout for Initial Page Load Fix
const [isInit, setisInit] = useState(false)
useEffect(() => {
setTimeout(function () {
setisInit(true)
}, 1000)
return () => {
setisInit(false)
}
}, [])
return(
<View>
...
{isInit && (
<FirebaseRecaptchaVerifierModal
ref={recaptchaVerifier}
firebaseConfig={app.options}
androidHardwareAccelerationDisabled={true}
androidLayerType="software"
attemptInvisibleVerification
/>
)}
...
<FirebaseRecaptchaBanner />
</View>
This was the magical line
androidLayerType="software"
I Hope Expo Updates there Documentation and avoid this painful experience for all of us Developers, I mean I literally never have seen an app with manual Recaptcha until im spamming
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.