Expo react-native app with firebase phone authentication在web上工作,在ios模拟器上出错,在Android上崩溃而没有警告

Posted

技术标签:

【中文标题】Expo react-native app with firebase phone authentication在web上工作,在ios模拟器上出错,在Android上崩溃而没有警告【英文标题】:Expo react-native app with firebase phone authentication works on web, error on ios simulator and crashes with no warning on Android 【发布时间】:2022-01-02 09:42:33 【问题描述】:

我正在使用 expo 构建一个 react-native 应用程序,我只有 2 个组件,WelcomeScreen 和 PhoneLoginScreen。我正在尝试实现在 Web 上运行良好的 firebase 电话身份验证,但在 ios 模拟器上我收到错误 Verifier._reset is not a function. (In 'verifier._reset()', 'verifiier._reset' is undefined,在 android 上,当我单击导航到 PhoneLoginScreen 组件的继续按钮时,它只会崩溃。代码如下:

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": 
    "@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"
  

我一直在谷歌上搜索,但没有任何效果。请指教

【问题讨论】:

【参考方案1】:

这是一个错误。 “expo-firebase-recaptcha”的维护者还没有发布修复,所以在那一天到来之前,这就是你自己修复它的方法:

进入node_modules/expo-firebase-recaptcha,打开build文件夹,找到FirebaseRecaptchaVerifierModal.js

在 FirebaseRecaptchaVerifierModal 内部,将以下函数添加到组件定义中:

_reset = () =&gt;

在添加空函数定义后,我已经包含了文件的 sn-p:

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,
        );
    ;
[...]

注意:您必须在每次安装 yarn/npm 或更改 node_modules 后执行此操作,直到发布者推送更新。

Error: verifier._reset is not a function. when trying to Sign in with phone using firebase, react native and Expo

【讨论】:

没用。还是有错误【参考方案2】:

FirebaseRecaptchaVerifierModal attemptInvisibleVerification Crashes on Android Emulator 看看这个。这对我很有帮助。

我补充:

<FirebaseRecaptchaVerifierModal ref=recaptchaVerifierRef
     firebaseConfig=firebaseConfig androidHardwareAccelerationDisabled
     attemptInvisibleVerification />

我的 FirebaseRecaptchaVerifierModal 上的这一行这将有助于解决我的问题。

【讨论】:

没用。应用仍然崩溃

以上是关于Expo react-native app with firebase phone authentication在web上工作,在ios模拟器上出错,在Android上崩溃而没有警告的主要内容,如果未能解决你的问题,请参考以下文章

React-Native 和 Expo:create-react-native-app 和 react-native init 之间的区别

对象不是 Expo(react-native) 应用程序中的函数

facebook登录错误,react-native ios expo

使用 react native / expo app (android) 打开已安装的应用程序

Expo react-native app with firebase phone authentication在web上工作,在ios模拟器上出错,在Android上崩溃而没有警告

Expo react-native:.png 图像未显示在 testflight 应用程序上(在开发中工作正常)