【问题标题】:The sms code has expired. Please re-send the verification code to try again短信代码已过期。请重新发送验证码重试
【发布时间】:2019-11-25 01:12:32
【问题描述】:

每当我尝试使用 react-native-firebase sdk 使用电话号码登录时,我都会通过短信收到 OTP 代码,当我提交收到的代码时,会出现错误提示:“短信代码已过期。请重新发送验证码再试一次。”这里需要注意的是,即使出现错误,相应电话号码的条目也会写入 Firebase 的用户部分。

我正在使用以下内容:

NodeJS: v8.11.1,
NPM: v5.6.0,
react-native: "^0.59.9",
react-native-firebase: "^5.5.3"

我已经尝试过的一些链接是:

1. https://github.com/invertase/react-native-firebase- 
docs/blob/master/docs/auth/phone-auth.md
2. https://stackoverflow.com/questions/46522726/firebase-phone- 
authentication-error-the-sms-code-has-expired
3. https://www.bountysource.com/issues/45308170-firebase-phone- 
number-auth-integration
4. https://medium.com/@chrisbianca/getting-started-with-firebase- 
authentication-on-react-native-a1ed3d2d6d91
5. https://invertase.io/oss/react-native-firebase/v6/auth/phone- 
auth

在 MobileRegistration.js 中:

navigateToOtpScreen() {
console.log("Phone number: ", "+91" + this.state.phoneNumber)
firebase.auth().signInWithPhoneNumber("+91" + 
this.state.phoneNumber)
.then(confirmResult => {
   this.setState({ confirmResult, message: 'Code has been sent!'})
   this.props.navigation.navigate('EnterOtp', { 'confirmResult': 
   confirmResult})
 })
 .catch(error => {
      alert(error.message);
      this.setState({ message: `Sign In With Phone Number Error: 
      ${error.message}` })
  });

};

在 EnterOtp.js 中:

componentDidMount() {
this.unsubscribe = firebase.auth().onAuthStateChanged((user) => {
    alert(JSON.stringify(user));
    if (user) {
        this.setState({
            user: user.toJSON()
        });
    } else {
        // User has been signed out, reset the state
        this.setState({
            user: null,
            message: '',
            otp: '',
            otp1: '',
            otp2: '',
            otp3: '',
            otp4: '',
            otp5: '',
            otp6: ''

        });
    }
});

}

componentWillUnmount() {
if (this.unsubscribe) this.unsubscribe();

}

verifyOTP = async () => {
const {
    confirmResult,
} = this.props.navigation.state.params;
let otp = this.state.otp + "" + this.state.otp1 + "" + this.state.otp2 + "" + this.state.otp3 + "" + this.state.otp4 + "" + this.state.otp5 + "" + this.state.otp6
if (confirmResult && otp.length) {

    alert(otp);
    confirmResult.confirm(otp).then((user) => {
            AsyncStorage.setItem('accessToken', confirmResult._verificationId);
            this.props.navigation.navigate('SetupCoverVideo');
            this.setState({
                message: 'Code Confirmed!'
            });
        })
        .catch(error => {
            alert(error.message) && this.setState({
                message: `Code Confirm Error: ${error.message}`
            })
        });
}

}

预期结果:应验证代码,并且应在 firebase 的用户部分中输入一个条目并导航到 SetupCoverVideo。

实际结果:遇到错误提示:“短信码已过期。请重新发送验证码重试。”这里需要注意的是,即使出现错误,相应电话号码的条目也会写入 Firebase 的用户部分。

我想知道解决方案。请任何人帮助我。

【问题讨论】:

  • 你有解决办法吗?
  • 我在任何地方都没有找到答案..

标签: react-native firebase-authentication react-native-android react-native-firebase


【解决方案1】:

显然,一些最新版本的 Android 足够智能,可以接收短信验证码并使用它来验证用户身份。此身份验证在后台进行,而用户仍会收到短信中的验证码。当用户尝试输入验证码时,他/她会收到一条消息,提示验证码已过期,因为 Android 已经使用它(在后台)并且已经登录了用户!要仔细检查,请检查 Firebase 控制台。您应该会发现这个新用户已添加到用户列表中。

为避免收到验证码过期消息,我们需要为“authentication changes”设置监听器。一旦 Android 在后台登录用户,这个监听器应该引导用户离开登录屏幕,他/她应该在登录屏幕中输入验证码。下面演示了如何实现这一点。我会将以下代码添加到登录屏幕。

与功能组件一起使用的示例代码:

useEffect( () => {
    firebase.auth().onAuthStateChanged( (user) => {
        if (user) {
            // Obviously, you can add more statements here, 
            //       e.g. call an action creator if you use Redux. 

            // navigate the user away from the login screens: 
            props.navigation.navigate("PermissionsScreen");
        } 
        else 
        {
            // reset state if you need to  
            dispatch({ type: "reset_user" });
        }
    });
}, []);  

与类组件一起使用的示例代码:

// I did NOT test this version, because I use functional components. 
componentDidMount() {
    firebase.auth().onAuthStateChanged( (user) => {
        if (user) {
            // Obviously, you can add more statements here, 
            //       e.g. call an action creator if you use Redux. 

            // navigate the user away from the login screens: 
            props.navigation.navigate("PermissionsScreen");
        } 
        else 
        {
            // reset state if you need to 
            this.setState({
                user: null,
                messageText: '',
                codeInput: '',
                phoneNo: '',
                confirmResult: null,
            });
        }
    });
};  

【讨论】:

  • else statement 中到底有什么好处我无法理解?
  • 据我了解,如果您的应用具有“注销”功能,则会执行 else 语句。我从未尝试过,因为我的应用没有注销选项。
  • @BilalAbdeen 您知道从哪个 Android 版本开始支持此功能吗?我需要知道,因为如果操作系统不自动验证,则需要一些代码进行手动验证
  • @Smurfy 如果我是你,我会确保我的代码支持手动验证。
  • @BilalAbdeen 验证成功后如何注销用户?因为在我的情况下,一旦为一个用户验证了 otp,它就会自动验证之前的每个用户,而不管使用的数字是多少
【解决方案2】:

您需要使用以下方法检查后台身份验证:

conponentDidMount() {    
firebase.auth().onAuthStateChanged((user) => {
            if (user) {
                // alert(JSON.stringify(user))
                // Obviously, you can add more statements here, 
                //       e.g. call an action creator if you use Redux. 
                // navigate the user away from the login screens: 
            }
        });
}

然后,您需要在完成后注销您的用户(我遇到了旧用户会话已经存在的问题,而新用户即将进行身份验证)

所以,在注销时使用:

if (firebase.auth().currentUser)
            firebase.auth().currentUser.delete();

一切准备就绪!

【讨论】:

    猜你喜欢
    • 2020-07-20
    • 2019-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-07
    • 1970-01-01
    • 2015-02-06
    • 1970-01-01
    相关资源
    最近更新 更多