繁体   English   中英

Firebase 使用 React Native 进行电话身份验证 Expo

[英]Firebase Phone Auth with React Native Expo

所以我一直在尝试在我的 React Native 项目中实现 firebase 电话认证。 我遵循了下面链接的这个很棒的教程,但遇到了将确认部分更改为不同页面而不是电话号码输入和代码输入都在同一页面上的问题。 我收到一条错误消息,指出未找到 verificationId,因为它在上一页中被调用。

教程链接

如果有人可以帮忙,那就太好了。

谢谢

  const const Login  = () => {
  const navigation =useNavigation();
  const [phoneNumber, setPhoneNumber] = useState();

  const [verificationId, setVerificationId] = useState(null);
  const recaptchaVerifier = useRef(null);




    const sendVerification  = () => {
       try {
    const phoneProvider = new firebase.auth.PhoneAuthProvider();
    phoneProvider
   .verifyPhoneNumber(phoneNumber, recaptchaVerifier.current)
   .then(setVerificationId);
     } catch (error) {
   alert(error);
     }
     navigation.navigate('OTPScreen', { verificationId: 
   verificationId})


     };
    return(
   

OTP屏幕

const const OTPScreen  = () => {

const verificationId = props.route.params.verificationId
 const [code, setCode] = useState('');


const confirmCode = () => {
  const credential = 
  firebase.auth.PhoneAuthProvider.credential(
    verificationId,
    code
  );
  firebase
    .auth()
    .signInWithCredential(credential)
    .then((result) => {
      console.log(result); 
      navigation.navigate('Home')  
        
    });
    

    };
   return(
   

我已经实施了两种可能的解决方案

  1. 将您的确认对象作为参数传递到新屏幕,然后将其用于 OTP 确认。
  2. 您还可以将此确认对象保存在像 redux 一样的全局存储中。

对于解决方案 1

const [confirm, setConfirm] = useState(null);


  async function signInWithPhoneNumber(phoneNumber) {
    const confirmation = await auth().signInWithPhoneNumber(phoneNumber);
    setConfirm(confirmation);
  }

然后导航到您的 otp 屏幕

navigation.navigate('otpScreen', {confirm: confirm})

在您的 otpScreen 上获取作为参数的确认对象(无论您使用的是什么,请对功能或类组件使用适当的语法)然后

const confirm = props.route.params.confirm

async function confirmCode() {
    try {
      await confirm.confirm(code);
    } catch (error) {
      console.log('Invalid code.');
    }
  }

完整的 firebase 电话验证完整代码是
check in android

import * as React from "react";
import { Text, View, TextInput, Button, StyleSheet, TouchableOpacity, Platform } from "react-native";
import { FirebaseRecaptchaVerifierModal } from "expo-firebase-recaptcha";
import * as firebase from "firebase";
try {
  firebase.initializeApp({
    apiKey: 'AIzaSyApGoaZVtoVTYnftHSbT9l7nDmDVUYJYpU',
      authDomain: 'playground-d4e7b.firebaseapp.com',
      databaseURL: 'https://playground-d4e7b.firebaseio.com',
      projectId: 'playground-d4e7b',
      storageBucket: 'playground-d4e7b.appspot.com',
      messagingSenderId: '903405300293',
      appId: '1:903405300293:web:c55227a2b8064da05d112c',
  });
} catch (err) {
  // ignore app already initialized error in snack
}

export default function App() {
  const recaptchaVerifier = React.useRef(null);
  const [phoneNumber, setPhoneNumber] = React.useState();
  const [verificationId, setVerificationId] = React.useState();
  const [verificationCode, setVerificationCode] = React.useState();
  const firebaseConfig = firebase.apps.length ? firebase.app().options : undefined;
  const [message, showMessage] = React.useState((!firebaseConfig || Platform.OS === 'web')
    ? { text: "To get started, provide a valid firebase config in App.js and open this snack on an iOS or Android device."}
    : undefined);

  return (
    <View style={{ padding: 20, marginTop: 50 }}>
      <FirebaseRecaptchaVerifierModal
        ref={recaptchaVerifier}
        firebaseConfig={firebaseConfig}
      />
      <Text style={{ marginTop: 20 }}>Enter phone number</Text>
      <TextInput
        style={{ marginVertical: 10, fontSize: 17 }}
        placeholder="+1 999 999 9999"
        autoFocus
        autoCompleteType="tel"
        keyboardType="phone-pad"
        textContentType="telephoneNumber"
        onChangeText={(phoneNumber) => setPhoneNumber(phoneNumber)}
      />
      <Button
        title="Send Verification Code"
        disabled={!phoneNumber}
        onPress={async () => {
          // The FirebaseRecaptchaVerifierModal ref implements the
          // FirebaseAuthApplicationVerifier interface and can be
          // passed directly to `verifyPhoneNumber`.
          try {
            const phoneProvider = new firebase.auth.PhoneAuthProvider();
            const verificationId = await phoneProvider.verifyPhoneNumber(
              phoneNumber,
              recaptchaVerifier.current
            );
            setVerificationId(verificationId);
            showMessage({
              text: "Verification code has been sent to your phone.",
            });
          } catch (err) {
            showMessage({ text: `Error: ${err.message}`, color: "red" });
          }
        }}
      />
      <Text style={{ marginTop: 20 }}>Enter Verification code</Text>
      <TextInput
        style={{ marginVertical: 10, fontSize: 17 }}
        editable={!!verificationId}
        placeholder="123456"
        onChangeText={setVerificationCode}
      />
      <Button
        title="Confirm Verification Code"
        disabled={!verificationId}
        onPress={async () => {
          try {
            const credential = firebase.auth.PhoneAuthProvider.credential(
              verificationId,
              verificationCode
            );
            await firebase.auth().signInWithCredential(credential);
            showMessage({ text: "Phone authentication successful 👍" });
          } catch (err) {
            showMessage({ text: `Error: ${err.message}`, color: "red" });
          }
        }}
      />
      {message ? (
        <TouchableOpacity
          style={[StyleSheet.absoluteFill, { backgroundColor: 0xffffffee, justifyContent: "center" }]}
          onPress={() => showMessage(undefined)}>
          <Text style={{color: message.color || "blue", fontSize: 17, textAlign: "center", margin: 20, }}>
            {message.text}
          </Text>
        </TouchableOpacity>
      ) : undefined}
    </View>
  );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM