React Native Firebase手机号认证:如何配置reCaptcha(无法用SafetyNet)
React Native Firebase手机号认证:切换reCaptcha替代SafetyNet
问题说明
使用Firebase手机号认证时触发错误(错误截图:
),因所在地区不在SafetyNet支持范围内,需改用reCaptcha完成认证。
实现步骤
1. Firebase控制台配置
- 进入Firebase控制台,打开目标项目的Authentication -> 登录方法,启用手机号认证
- 在项目设置 -> 常规标签下,确认已添加你的React Native应用(Android/iOS)
2. 保留原Firebase初始化代码
原配置无需改动,继续使用:
import firebase from '@react-native-firebase/app'; import auth from '@react-native-firebase/auth'; const firebaseConfig = { apiKey: 'xxxxxxxxxxxx', authDomain: 'xxxxxxxxxxxxx', projectId: 'xxxxxxxxxxxxx', storageBucket: 'xxxxxxxxxxxxxx', messagingSenderId: 'xxxxxxxxxxxxx', appId: 'xxxxxxxxxxxxxxx', measurementId: 'xxxxxxxxxxxxxx', }; if (!firebase.apps.length) { firebase.initializeApp(firebaseConfig); } export default () => { return { firebase, auth }; };
3. 重写SignUPScreen组件(添加reCaptcha验证)
引入RecaptchaVerifier并完成验证逻辑:
import { useState, useEffect } from 'react'; import { View, TextInput, Button, Alert, StyleSheet } from 'react-native'; import { RecaptchaVerifier } from '@react-native-firebase/auth'; import firebaseSetup from './firebaseSetup'; const SignUPScreen = ({ navigation }) => { const { auth } = firebaseSetup(); const [confirm, setConfirm] = useState(null); const [phoneNumber, setPhoneNumber] = useState(''); const [verifier, setVerifier] = useState(null); useEffect(() => { const recaptchaVerifier = new RecaptchaVerifier('recaptcha-container', { size: 'invisible', // 隐藏式自动验证,无需用户手动操作 callback: () => {}, 'expired-callback': () => Alert.alert('验证过期,请重新操作') }, auth()); setVerifier(recaptchaVerifier); }, [auth]); const signIn = async () => { if (!verifier) { Alert.alert('验证器未就绪,请稍后重试'); return; } try { const confirmation = await auth().signInWithPhoneNumber(phoneNumber, verifier); setConfirm(confirmation); navigation.navigate('OTP', { confirm: confirmation }); } catch (error) { Alert.alert('认证失败', error.message); } }; return ( <View style={styles.container}> {/* 必须保留此空View作为reCaptcha的挂载容器 */} <View id="recaptcha-container" /> <TextInput style={styles.textInput} placeholder="输入手机号(带国家码,如+8613xxxxxxxxx)" keyboardType="phone-pad" onChangeText={setPhoneNumber} value={phoneNumber} /> <Button title="获取验证码" onPress={signIn} /> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', paddingHorizontal: 20, }, textInput: { borderBottomWidth: 1, marginBottom: 20, paddingVertical: 10, }, }); export default SignUPScreen;
4. OTP组件优化(可选)
保留原逻辑,优化错误提示和输入限制:
import { useState } from 'react'; import { Alert, Button, StyleSheet, View } from 'react-native'; import { TextInput } from 'react-native-paper'; const OTP = ({ route }) => { const { confirm } = route.params; const [code, setCode] = useState(''); const confirmCode = async () => { try { await confirm.confirm(code); Alert.alert('认证成功', '用户登录成功'); } catch (error) { Alert.alert('验证码错误', '请输入正确的6位验证码'); } }; return ( <View style={styles.container}> <TextInput style={styles.textInput} placeholder="输入6位验证码" value={code} onChangeText={setCode} keyboardType="number-pad" maxLength={6} /> <Button title="确认验证码" onPress={confirmCode} /> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', paddingHorizontal: 20, }, textInput: { marginBottom: 20, }, }); export default OTP;
关键注意事项
- 手机号必须包含国家码前缀(如+86),否则会触发认证失败
size: 'invisible'为隐藏式验证,系统自动完成,无需用户交互- 必须保留
id="recaptcha-container"的空View,否则reCaptcha无法正常初始化
内容的提问来源于stack exchange,提问作者Asem Qoraishi
相关产品推荐
相关产品推荐

