firebase身份验证电话不向已通过身份验证的用户发送短信

firebase身份验证电话不向已通过身份验证的用户发送短信,firebase,react-native,firebase-authentication,Firebase,React Native,Firebase Authentication,我正在尝试在react native应用程序中使用firebase实现电话身份验证。 我只是看到,如果用户已经用电话号码注册(存在于firebase控制台的已验证表中),并且他注销并想用同一部电话再次注册,我就不会再收到sms代码。我得到verificationId null,它抛出错误 TypeError:无法读取null的属性“length” 在这行代码中 {started && auto && !codeInput && !codeInp

我正在尝试在react native应用程序中使用firebase实现电话身份验证。 我只是看到,如果用户已经用电话号码注册(存在于firebase控制台的已验证表中),并且他注销并想用同一部电话再次注册,我就不会再收到sms代码。我得到verificationId null,它抛出错误

TypeError:无法读取null的属性“length”

在这行代码中

  {started && auto && !codeInput && !codeInput.length
        ? this.renderAutoVerifyProgress()
        : null}
我的完整代码

    import React, { Component } from 'react';
import {
  View,
  Button,
  Text,
  TextInput,
  Image,
  ActivityIndicator,
  Platform,
} from 'react-native';
import firebase from 'react-native-firebase';


const imageUrl =
  'https://www.shareicon.net/data/512x512/2016/07/19/798524_sms_512x512.png';

export default class PhoneAuth extends Component {
  static getDefaultState() {
    return {
      error: '',
      codeInput: '',
      phoneNumber: '+972',
      auto: Platform.OS === 'android',
      autoVerifyCountDown: 0,
      sent: false,
      started: false,
      user: null,
    };
  }

  constructor(props) {
    super(props);
    this.timeout = 20;
    this._autoVerifyInterval = null;
    this.state = PhoneAuth.getDefaultState();
  }

  _tick() {
    this.setState({
      autoVerifyCountDown: this.state.autoVerifyCountDown - 1,
    });
  }

  /**
   * Called when confirm code is pressed - we should have the code and verificationId now in state.
   */
  afterVerify = () => {
    const { codeInput, verificationId } = this.state;
    const credential = firebase.auth.PhoneAuthProvider.credential(
      verificationId,
      codeInput
    );

    // TODO do something with credential for example:
    firebase
      .auth()
      .signInWithCredential(credential)
      .then(user => {
        console.log('PHONE AUTH USER ->>>>>', user.toJSON());
        this.setState({ user: user.toJSON() });
      })
      .catch(console.error);
  };

  signIn = () => {
    const { phoneNumber } = this.state;
    this.setState(
      {
        error: '',
        started: true,
        autoVerifyCountDown: this.timeout,
      },
      () => {
        firebase
          .auth()
          .verifyPhoneNumber(phoneNumber)
          .on('state_changed', phoneAuthSnapshot => {
            console.log(phoneAuthSnapshot);
            switch (phoneAuthSnapshot.state) {
              case firebase.auth.PhoneAuthState.CODE_SENT: // or 'sent'
                // update state with code sent and if android start a interval timer
                // for auto verify - to provide visual feedback
                this.setState(
                  {
                    sent: true,
                    verificationId: phoneAuthSnapshot.verificationId,
                    autoVerifyCountDown: this.timeout,
                  },
                  () => {
                    if (this.state.auto) {
                      this._autoVerifyInterval = setInterval(
                        this._tick.bind(this),
                        1000
                      );
                    }
                  }
                );
                break;
              case firebase.auth.PhoneAuthState.ERROR: // or 'error'
                // restart the phone flow again on error
                clearInterval(this._autoVerifyInterval);
                this.setState({
                  ...PhoneAuth.getDefaultState(),
                  error: phoneAuthSnapshot.error.message,
                });
                break;

              // ---------------------
              // ANDROID ONLY EVENTS
              // ---------------------
              case firebase.auth.PhoneAuthState.AUTO_VERIFY_TIMEOUT: // or 'timeout'
                clearInterval(this._autoVerifyInterval);
                this.setState({
                  sent: true,
                  auto: false,
                  verificationId: phoneAuthSnapshot.verificationId,
                });
                break;
              case firebase.auth.PhoneAuthState.AUTO_VERIFIED: // or 'verified'
                clearInterval(this._autoVerifyInterval);
                this.setState({
                  sent: true,
                  codeInput: phoneAuthSnapshot.code,
                  verificationId: phoneAuthSnapshot.verificationId,
                });
                break;
              default:
              // will never get here - just for linting
            }
          });
      }
    );
  };

  renderInputPhoneNumber() {
    const { phoneNumber } = this.state;
    return (
      <View style={{ flex: 1 }}>
        <Text>Enter phone number:</Text>
        <TextInput
          autoFocus
          style={{ height: 40, marginTop: 15, marginBottom: 15 }}
          onChangeText={value => this.setState({ phoneNumber: value })}
          placeholder="Phone number ... "
          value={phoneNumber}
        />
        <Button
          title="Begin Verification"
          color="green"
          onPress={this.signIn}
        />
      </View>
    );
  }

  renderSendingCode() {
    const { phoneNumber } = this.state;

    return (
      <View style={{ paddingBottom: 15 }}>
        <Text style={{ paddingBottom: 25 }}>
          {`Sending verification code to '${phoneNumber}'.`}
        </Text>
        <ActivityIndicator animating style={{ padding: 50 }} size="large" />
      </View>
    );
  }

  renderAutoVerifyProgress() {
    const {
      autoVerifyCountDown,
      started,
      error,
      sent,
      phoneNumber,
    } = this.state;
    if (!sent && started && !error.length) {
      return this.renderSendingCode();
    }
    return (
      <View style={{ padding: 0 }}>
        <Text style={{ paddingBottom: 25 }}>
          {`Verification code has been successfully sent to '${phoneNumber}'.`}
        </Text>
        <Text style={{ marginBottom: 25 }}>
          {`We'll now attempt to automatically verify the code for you. This will timeout in ${autoVerifyCountDown} seconds.`}
        </Text>
        <Button
          style={{ paddingTop: 25 }}
          title="I have a code already"
          color="green"
          onPress={() => this.setState({ auto: false })}
        />
      </View>
    );
  }

  renderError() {
    const { error } = this.state;

    return (
      <View
        style={{
          padding: 10,
          borderRadius: 5,
          margin: 10,
          backgroundColor: 'rgb(255,0,0)',
        }}
      >
        <Text style={{ color: '#fff' }}>{error}</Text>
      </View>
    );
  }

  render() {
    const { started, error, codeInput, sent, auto, user } = this.state;
    return (
      <View
        style={{ flex: 1, backgroundColor: user ? 'rgb(0, 200, 0)' : '#fff' }}
      >
        <View
          style={{
            padding: 5,
            justifyContent: 'center',
            alignItems: 'center',
            flex: 1,
          }}
        >
          <Image
            source={{ uri: imageUrl }}
            style={{
              width: 128,
              height: 128,
              marginTop: 25,
              marginBottom: 15,
            }}
          />
          <Text style={{ fontSize: 25, marginBottom: 20 }}>
            Phone Auth Example
          </Text>
          {error && error.length ? this.renderError() : null}
          {!started && !sent ? this.renderInputPhoneNumber() : null}
          {started && auto && !codeInput && !codeInput.length
            ? this.renderAutoVerifyProgress()
            : null}
          {!user && started && sent && (codeInput && codeInput.length || !auto) ? (
            <View style={{ marginTop: 15 }}>
              <Text>Enter verification code below:</Text>
              <TextInput
                autoFocus
                style={{ height: 40, marginTop: 15, marginBottom: 15 }}
                onChangeText={value => this.setState({ codeInput: value })}
                placeholder="Code ... "
                value={codeInput}
              />
              <Button
                title="Confirm Code"
                color="#841584"
                onPress={this.afterVerify}
              />
            </View>
          ) : null}
          {user ? (
            <View style={{ marginTop: 15 }}>
              <Text>{`Signed in with new user id: '${user.uid}'`}</Text>
            </View>
          ) : null}
        </View>
      </View>
    );
  }
}
import React,{Component}来自'React';
进口{
看法
按钮
文本,
文本输入,
形象,,
活动指示器,
平台,
}从“反应本机”;
从“react native firebase”导入firebase;
常量图像URL=
'https://www.shareicon.net/data/512x512/2016/07/19/798524_sms_512x512.png';
导出默认类PhoneAuth扩展组件{
静态getDefaultState(){
返回{
错误:“”,
代码输入:“”,
电话号码:'+972',
auto:Platform.OS===“android”,
自动验证倒计时:0,
发送:错误,
开始:错,
用户:null,
};
}
建造师(道具){
超级(道具);
这是超时=20;
这是。_autoVerifyInterval=null;
this.state=PhoneAuth.getDefaultState();
}
_勾选(){
这是我的国家({
autoVerifyCountDown:this.state.autoVerifyCountDown-1,
});
}
/**
*当按下确认代码时调用-我们应该使代码和verificationId现在处于状态。
*/
afterVerify=()=>{
const{codeInput,verificationId}=this.state;
const credential=firebase.auth.PhoneAuthProvider.credential(
验证ID,
代码输入
);
//TODO使用凭证执行某些操作,例如:
火基
.auth()
.signiWithCredential(凭证)
。然后(用户=>{
log('PHONE AUTH USER->>>>,USER.toJSON());
this.setState({user:user.toJSON()});
})
.catch(控制台错误);
};
签名=()=>{
const{phoneNumber}=this.state;
这是我的国家(
{
错误:“”,
开始:是的,
autoVerifyCountDown:此为.timeout,
},
() => {
火基
.auth()
.verifyPhoneNumber(电话号码)
.on('state_changed',phoneAuthSnapshot=>{
日志(phoneAuthSnapshot);
开关(phoneAuthSnapshot.state){
case firebase.auth.PhoneAuthState.CODE_SENT://或“SENT”
//使用发送的代码更新状态,如果android启动间隔计时器
//用于自动验证-提供视觉反馈
这是我的国家(
{
是的,
verificationId:phoneAuthSnapshot.verificationId,
autoVerifyCountDown:此为.timeout,
},
() => {
if(this.state.auto){
这是。_autoVerifyInterval=setInterval(
这个。_勾选绑定(这个),
1000
);
}
}
);
打破
案例firebase.auth.PhoneAuthState.ERROR://或“ERROR”
//出现错误时重新启动电话流
clearInterval(此为自动验证间隔);
这是我的国家({
…PhoneAuth.getDefaultState(),
错误:phoneAuthSnapshot.error.message,
});
打破
// ---------------------
//仅ANDROID事件
// ---------------------
case firebase.auth.PhoneAuthState.AUTO\u VERIFY\u TIMEOUT://或“TIMEOUT”
clearInterval(此为自动验证间隔);
这是我的国家({
是的,
汽车:错,
verificationId:phoneAuthSnapshot.verificationId,
});
打破
案例firebase.auth.PhoneAuthState.AUTO_VERIFIED://或“VERIFIED”
clearInterval(此为自动验证间隔);
这是我的国家({
是的,
codeInput:phoneAuthSnapshot.code,
verificationId:phoneAuthSnapshot.verificationId,
});
打破
违约:
//永远都不会到这里来-只是为了皮棉
}
});
}
);
};
renderInputPhoneNumber(){
const{phoneNumber}=this.state;
返回(
输入电话号码:
this.setState({phoneNumber:value})
占位符=“电话号码…”
值={phoneNumber}
/>
);
}
renderSendingCode(){
const{phoneNumber}=this.state;
返回(
{`正在向${phoneNumber}发送验证码。`}
);
}
renderAutoVerifyProgress(){
常数{
自动验证倒计时,
起动,
错误,
发送,
电话号码,
}=本州;
如果(!sent&&start&&!error.length){
返回此.renderSendingCode();
}
返回(
{`验证码已成功发送到${phoneNumber}。`}
{`我们现在将尝试为您自动验证代码。这将在${autoVerifyCountDown}秒后超时。`}
this.setState({auto:false})
/>
);
}
渲染器(){
const{error}=this.state;
返回(
{错误}
);
}
render(){
const{started,error,codeInput,sent,auto,user}=this.state;
返回(
电话验证示例
{error&&error.length?this.renderError():null}
{!已启动&!已发送?this.renderInputPhoneNumber():null}
{started&&auto&&!codeInput&&!codeInput.length
?这是我的名字