Expo SDK50中expo-firebase-recaptcha失效及手机号登录实现咨询
在Expo SDK 50中实现Firebase手机号登录(带reCAPTCHA验证)的解决方案
问题根源
expo-firebase-recaptcha依赖WebView组件,但直接安装第三方react-native-web-view会和Expo Go内置的WebView版本冲突,导致应用无法启动。必须使用Expo官方适配的WebView包。
步骤1:修复WebView依赖冲突
- 卸载手动安装的非Expo版WebView:
npm uninstall react-native-web-view # 或 yarn remove react-native-web-view
- 安装Expo官方适配的WebView包:
npx expo install react-native-web-view
步骤2:配置Firebase基础依赖
- 安装Expo Firebase核心包:
npx expo install expo-firebase-app expo-firebase-auth
- 在Firebase控制台开启手机号/密码登录方式,并添加你的Android应用的SHA-1指纹(这一步必须做,否则验证码无法发送)。
- 将Firebase项目配置信息复制到代码中(从控制台的"添加应用"流程获取)。
步骤3:实现手机号登录组件
以下是完整的可运行示例代码,包含reCAPTCHA验证和验证码流程:
import React, { useState, useRef } from 'react'; import { View, TextInput, Button, Alert, StyleSheet } from 'react-native'; import { FirebaseRecaptchaVerifierModal } from 'expo-firebase-recaptcha'; import { getAuth, signInWithPhoneNumber } from 'firebase/auth'; import { initializeApp } from 'firebase/app'; // 替换为你的Firebase项目配置 const firebaseConfig = { apiKey: "YOUR_API_KEY", authDomain: "YOUR_AUTH_DOMAIN", projectId: "YOUR_PROJECT_ID", storageBucket: "YOUR_STORAGE_BUCKET", messagingSenderId: "YOUR_SENDER_ID", appId: "YOUR_APP_ID" }; const app = initializeApp(firebaseConfig); const auth = getAuth(app); export default function PhoneLogin() { const [phoneNumber, setPhoneNumber] = useState(''); const [verificationCode, setVerificationCode] = useState(''); const [confirm, setConfirm] = useState(null); const recaptchaVerifier = useRef(null); const sendVerificationCode = async () => { if (!phoneNumber) { Alert.alert('提示', '请输入正确格式的手机号(如+8613xxxxxxxxx)'); return; } try { const verifier = new auth.RecaptchaVerifier( recaptchaVerifier.current, { size: 'invisible' } ); const confirmation = await signInWithPhoneNumber(auth, phoneNumber, verifier); setConfirm(confirmation); Alert.alert('验证码已发送至你的手机'); } catch (err) { Alert.alert('错误', err.message); } }; const verifyCode = async () => { if (!verificationCode) { Alert.alert('提示', '请输入验证码'); return; } try { await confirm.confirm(verificationCode); Alert.alert('登录成功!'); // 这里可以跳转到主页或处理用户信息 } catch (err) { Alert.alert('错误', '验证码无效或已过期'); } }; return ( <View style={styles.container}> {/* 隐藏的reCAPTCHA验证组件 */} <FirebaseRecaptchaVerifierModal ref={recaptchaVerifier} firebaseConfig={firebaseConfig} /> <TextInput style={styles.input} placeholder="输入手机号(格式:+8613xxxxxxxxx)" value={phoneNumber} onChangeText={setPhoneNumber} keyboardType="phone-pad" autoCapitalize="none" /> {!confirm ? ( <Button title="发送验证码" onPress={sendVerificationCode} /> ) : ( <> <TextInput style={styles.input} placeholder="输入6位验证码" value={verificationCode} onChangeText={setVerificationCode} keyboardType="number-pad" maxLength={6} /> <Button title="验证并登录" onPress={verifyCode} /> </> )} </View> ); } const styles = StyleSheet.create({ container: { flex: 1, padding: 20, justifyContent: 'center', }, input: { marginBottom: 20, padding: 12, borderWidth: 1, borderColor: '#ddd', borderRadius: 4, }, });
步骤4:解决Expo Go启动问题的额外技巧
- 清理Expo缓存后重启项目:
npx expo start --clear
- 确保所有依赖都是Expo官方支持的版本,避免安装非Expo的原生模块。
- 检查
app.json中是否有冲突的插件配置,比如重复的WebView相关配置。
内容的提问来源于stack exchange,提问作者Luis Castellon
相关产品推荐
相关产品推荐

