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

2022 Expo(React Native)如何无eject实现Firebase手机号认证

Expo SDK 44 免Eject接入Firebase 9.x手机号认证方案

完全可以实现,不需要执行eject操作。旧的Firebase 8适配教程失效是因为Firebase 9版本换成了模块化API,接口调用方式和8版本的命名空间写法差异很大,按照下面的步骤配置就能跑通:

  • 依赖安装
    执行以下命令安装兼容SDK 44的对应版本依赖,不要自行装过高版本避免兼容问题:

    expo install firebase@9.8.4 expo-firebase-recaptcha react-native-webview
    
  • Firebase控制台前置配置

    1. 进入对应项目的Authentication面板,开启手机号登录方式
    2. 在项目设置中添加Web应用,复制生成的Web端firebaseConfig配置项,不要使用iOS/Android原生端的配置
    3. 把开发阶段要用的测试手机号添加到手机号认证测试白名单,跳过真实短信下发和风控校验
  • 核心实现代码(适配Firebase 9.8.4模块化API)
    首先完成Firebase初始化:

    import { initializeApp } from 'firebase/app';
    import { getAuth, signInWithPhoneNumber, signInWithCredential, PhoneAuthProvider } from 'firebase/auth';
    import { FirebaseRecaptchaVerifierModal } from 'expo-firebase-recaptcha';
    
    // 替换为你自己的Firebase Web端配置
    const firebaseConfig = {
      apiKey: "",
      authDomain: "",
      projectId: "",
      storageBucket: "",
      messagingSenderId: "",
      appId: ""
    };
    
    const app = initializeApp(firebaseConfig);
    const auth = getAuth(app);
    

    登录页面逻辑参考:

    import React, { useState, useRef } from 'react';
    import { View, TextInput, Button, StyleSheet } from 'react-native';
    
    export default function PhoneLogin() {
      const recaptchaVerifier = useRef(null);
      const [phoneNumber, setPhoneNumber] = useState('');
      const [verifyCode, setVerifyCode] = useState('');
      const [verificationId, setVerificationId] = useState(null);
    
      const sendCode = async () => {
        try {
          const verifier = recaptchaVerifier.current;
          const phoneRes = await signInWithPhoneNumber(auth, phoneNumber, verifier);
          setVerificationId(phoneRes.verificationId);
        } catch (err) {
          console.log('验证码发送失败:', err);
        }
      };
    
      const login = async () => {
        try {
          const credential = PhoneAuthProvider.credential(verificationId, verifyCode);
          const res = await signInWithCredential(auth, credential);
          // 登录成功,可从res.user获取用户信息做后续跳转
          console.log('登录成功', res.user);
        } catch (err) {
          console.log('登录失败:', err);
        }
      };
    
      return (
        <View style={styles.container}>
          <FirebaseRecaptchaVerifierModal
            ref={recaptchaVerifier}
            firebaseConfig={firebaseConfig}
            attemptInvisibleVerification={true}
          />
          {!verificationId ? (
            <>
              <TextInput
                style={styles.input}
                placeholder="输入手机号(格式:+8613xxxxxxxxx)"
                keyboardType="phone-pad"
                value={phoneNumber}
                onChangeText={setPhoneNumber}
              />
              <Button title="发送验证码" onPress={sendCode} />
            </>
          ) : (
            <>
              <TextInput
                style={styles.input}
                placeholder="输入6位验证码"
                keyboardType="number-pad"
                value={verifyCode}
                onChangeText={setVerifyCode}
              />
              <Button title="确认登录" onPress={login} />
            </>
          )}
        </View>
      )
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        padding: 24,
        justifyContent: 'center'
      },
      input: {
        borderWidth: 1,
        borderColor: '#ddd',
        borderRadius: 8,
        padding: 12,
        marginBottom: 16
      }
    })
    
  • 常见踩坑说明

    • 必须使用Firebase Web SDK实现,不要尝试接入原生端的Firebase认证模块,免eject的Expo环境不支持编译自定义原生代码
    • 手机号必须带国际区号前缀,缺失区号会直接报无效参数错误
    • FirebaseRecaptchaVerifierModal组件不要做条件渲染,必须常驻页面渲染树,否则ref无法获取实例会导致reCAPTCHA初始化失败
    • 如果遇到reCAPTCHA无法加载的问题,在app.json的expo配置节点下添加"scheme": "你的项目自定义名称",重启开发服务即可
    • 生产环境如果要开隐形reCAPTCHA校验,需要在Firebase控制台把Expo应用的域名加到授权域名列表里

内容的提问来源于stack exchange,提问作者dany

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 15:39:25