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

Firebase 9 + React Context:如何限制未注册用户登录?

问题修复方案

你的问题核心是Context里的认证函数没有返回Promise,导致登录页面的await根本没等到Firebase的认证请求完成,不管请求成功失败,代码都会直接执行跳转逻辑。

第一步:修复Context中的认证函数

Firebase的createUserWithEmailAndPassword和signInWithEmailAndPassword本身返回Promise,但你的代码里没有把这个Promise返回出去,导致await无效。修改Context代码:

const UserContext = createContext();

export const AuthContextProvider = ({ children }) => {
  const [user, setUser] = useState({});

  // 返回Firebase方法的Promise,让await可以等待
  const createUser = (email, password) => {
    return createUserWithEmailAndPassword(authentication, email, password);
  };
  // 同样返回Promise
  const signUser = (email, password) => {
    return signInWithEmailAndPassword(authentication, email, password);
  };

  const logOut = () => {
    return signOut(authentication);
  };

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(authentication, (currenUser) => {
      setUser(currenUser);
    });
    return () => {
      unsubscribe();
    };
  }, []);

  return (
    <UserContext.Provider value={{ createUser, signUser, user, logOut }}>
      {children}
    </UserContext.Provider>
  );
};

export const UserAuth = () => {
  return useContext(UserContext);
};

第二步:完善登录页面的错误处理

现在await会正确等待认证请求,只有成功时才跳转,失败时捕获错误并提示用户:

const SignIn = ({ navigation }) => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [showErr, setShowErr] = useState('');

  const { user, signUser } = UserAuth();

  const handleSignIn = async () => {
    setShowErr(''); // 清空之前的错误提示
    try {
      // 等待认证请求完成
      await signUser(email, password);
      // 仅当认证成功时跳转首页
      navigation.navigate('Home');
    } catch (e) {
      // 根据Firebase错误码给出针对性提示
      switch(e.code) {
        case 'auth/user-not-found':
          setShowErr('该邮箱未注册,请先完成注册');
          break;
        case 'auth/wrong-password':
          setShowErr('密码错误,请重试');
          break;
        default:
          setShowErr('登录失败,请稍后再试');
      }
      console.log(e.message);
    }
  };

  return (
    <View
    {...}
    >
      {/* 渲染错误提示 */}
      {showErr && <Text style={{color: 'red', marginTop: 10}}>{showErr}</Text>}
    </View>
  );
};

export default SignIn;

原理说明

Firebase的认证操作是异步的,必须返回它的Promise,await才能正确等待操作结果。之前的代码因为没有返回Promise,await signUser(...)会直接跳过等待执行跳转,此时Firebase的认证请求还在处理中,错误也无法被捕获。修改后,只有认证成功(Promise状态为resolved)才会跳转,失败时(Promise状态为rejected)会进入catch块处理错误,自然就能拦截未注册用户的登录请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 19:40:29