React Native Firebase手机号认证报错:无法创建PhoneAuthCredential
错误原因分析
核心问题:未触发OTP发送逻辑
你的Verify按钮没有绑定sendOtp函数,用户点击后不会调用Firebase的signInWithPhoneNumber接口,导致confirmData始终是初始的空字符串。此时调用confirmData.confirm()时,由于没有有效的PhoneAuthConfirmation对象,Firebase无法生成PhoneAuthCredential,从而抛出该错误。
次要问题
- PhoneInput同时绑定了
onChangeText和onChangeFormattedText,两者会互相覆盖手机号值,可能导致传给Firebase的手机号格式不符合E.164标准(Firebase要求手机号必须是带国家码的格式,比如+1234567890)。 confirmData初始值设为空字符串,而非null,不利于后续判断是否已获取有效的确认对象。
解决办法
1. 给Verify按钮绑定sendOtp函数
修改Verify按钮的代码,添加onPress事件:
<TouchableOpacity style={styles.buttonStyle} onPress={sendOtp}> <Text style={styles.buttonText}>Verify</Text> </TouchableOpacity>
2. 修正PhoneInput的手机号绑定逻辑
只保留onChangeFormattedText来获取符合E.164格式的手机号,去掉onChangeText避免格式冲突:
<PhoneInput style={styles.inputStyle} defaultValue={PhoneNumber} defaultCode="DM" layout="first" keyboardType="number-pad" onChangeFormattedText={text => setPhoneNumber(text)} />
3. 优化confirmData初始值与提交前校验
将confirmData初始值设为null,并在submitOtp中先校验是否存在有效确认对象:
const [confirmData, setConfirmData] = useState(null); const submitOtp = async () => { if (!confirmData) { Alert.alert('请先点击Verify获取OTP'); return; } try { const response = await confirmData.confirm(otpInput); console.log(response); Alert.alert('Your Number is verified'); } catch (error) { console.log(error); Alert.alert('OTP验证失败,请检查输入'); } }
完整修正后的代码
import React, {useState} from 'react'; import { View, Text, StyleSheet, Image, TextInput, TouchableOpacity, Alert, } from 'react-native'; import PhoneInput from 'react-native-phone-number-input'; import auth from '@react-native-firebase/auth'; const Login = () => { const [PhoneNumber, setPhoneNumber] = useState(''); const [otpInput, setOtpInput] = useState(''); const [confirmData, setConfirmData] = useState(null); const sendOtp = async () => { if (!PhoneNumber) { Alert.alert('请输入手机号'); return; } try { const response = await auth().signInWithPhoneNumber(PhoneNumber); setConfirmData(response); console.log(response); Alert.alert('OTP已发送,请验证'); } catch (error) { console.log(error); Alert.alert('发送OTP失败,请检查手机号格式'); } } const submitOtp = async () => { if (!confirmData) { Alert.alert('请先点击Verify获取OTP'); return; } if (!otpInput) { Alert.alert('请输入OTP'); return; } try { const response = await confirmData.confirm(otpInput); console.log(response); Alert.alert('手机号验证成功'); } catch (error) { console.log(error); Alert.alert('OTP验证失败,请检查输入'); } } return ( <View> <View style={styles.con}> <Text style={styles.container}>Login Screen</Text> <Image source={require('../assets/logo.png')} style={styles.image} /> </View> <View style={styles.inputContainer}> <Text style={styles.labels}>Phone Number:</Text> <PhoneInput style={styles.inputStyle} defaultValue={PhoneNumber} defaultCode="DM" layout="first" keyboardType="number-pad" onChangeFormattedText={text => setPhoneNumber(text)} /> </View> <View> <TouchableOpacity style={styles.buttonStyle} onPress={sendOtp}> <Text style={styles.buttonText}>Verify</Text> </TouchableOpacity> </View> <View style={styles.otpContainer}> <TextInput style={styles.otpStyle} placeholder="Enter OTP" autoCapitalize="none" secureTextEntry={true} onChangeText={(value) => setOtpInput(value)}/> </View> <View> <TouchableOpacity style={styles.continueStyle}> <Text style={styles.buttonText} onPress={submitOtp}> Continue </Text> </TouchableOpacity> </View> </View> ); }; export default Login;
额外注意事项
- 确保Firebase控制台已启用手机号认证方式。
- 测试时使用真实设备(模拟器可能无法接收短信OTP,部分安卓模拟器支持,但iOS模拟器通常不行)。
- 确认手机号格式正确,必须是E.164标准(如
+18091234567),PhoneInput的onChangeFormattedText会自动处理这个格式。
内容的提问来源于stack exchange,提问作者SANCHITA CHOWDHURY
相关产品推荐
相关产品推荐

