You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 18:58:33