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

React Native Firebase v6中Firebase安全规则request.auth为null问题排查

Expo React Native谷歌登录后Firestore规则认证异常问题

问题描述

在Expo托管的React Native应用中,使用@react-native-firebase和@react-native-google-signin实现谷歌登录,用户完成认证后auth().currentUser可正确返回用户对象,但Firestore规则设置为request.auth != null时会拒绝文档获取请求,设置为request.auth == null时反而允许访问。

当前Firestore规则

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

React Native相关代码

谷歌登录函数

const signInWithGoogle = async () => {
    try {
      setLoading(true);
      await GoogleSignin.hasPlayServices({
        showPlayServicesUpdateDialog: true,
      });
      const { idToken } = await GoogleSignin.signIn();
      const googleCredential = auth.GoogleAuthProvider.credential(idToken);
      auth()
        .signInWithCredential(googleCredential)
        .then(async (data) => {
          await setUserInFirestore(data.user);
          const { uid, displayName, email, photoURL } = data.user;
          await AsyncStorage.setItem(
            "user",
            JSON.stringify({ uid, displayName, email, photoURL })
          );
          if (data.user?.metadata) {
            const date = data.user.metadata.creationTime.slice(0, 10);
            await AsyncStorage.setItem("userDate", date);
          }
        })
        .catch((error) => {
          setError(error);
          navigation.navigate(routes.WELCOME);
        });
    } catch (error) {
      setError(error);
      navigation.navigate(routes.WELCOME);
    }
  };

setUserInFirestore方法

const setUserInFirestore = async (user) => {
    const { uid, displayName, email, photoURL } = user;

    try {
      const userRef = doc(db, "users", uid);
      const snapshot = await getDoc(userRef);

      if (!snapshot.exists()) {
        await setDoc(userRef, {
          displayName,
          email,
          photoURL,
          uid,
          subscription: null,
          createdAt: new Date(),
        });
        setIsNewUser(true);
      }
      setUser(user);
      setUserContext(user);
    } catch (error) {
      setError(error);
    }
  };

初始化代码

useEffect(() => {
    GoogleSignin.configure({
      webClientId: key,
    });

    const unsubscribe = auth().onAuthStateChanged((user) => {
      setUser(user);
      setLoading(false);
    });

    return unsubscribe;
  }, []);

已尝试的解决方案

  • 全局更新firebase-tools,无效果

使用的依赖版本

  • "firebase": "^9.21.0"
  • "@react-native-firebase/app": "^17.4.3"
  • "@react-native-firebase/auth": "^17.4.3"

解决方案

  1. 统一Firestore实例来源
    确保Firestore实例使用@react-native-firebase/firestore初始化,而非web版firebase/firestore。RN环境下@react-native-firebase的实例会自动同步Auth会话,web版无法关联RN的Auth状态:

    // 正确导入方式
    import firestore from '@react-native-firebase/firestore';
    const db = firestore();
    

    移除项目中web版firebase依赖,避免版本冲突。

  2. 强制刷新Auth令牌
    在用户登录成功后,强制刷新ID令牌,确保Firestore请求使用最新的有效令牌:
    在signInWithCredential的then回调中添加:

    await data.user.getIdToken(true); // 强制刷新令牌
    
  3. 调试Firestore规则中的auth状态
    在规则中添加调试语句,查看request.auth的实际值:

    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        match /{document=**} {
          allow read, write: if request.auth != null || debug(request.auth);
        }
      }
    }
    

    通过Firebase控制台的规则模拟器测试,或查看规则执行日志,确认request.auth是否为null。

  4. 检查Firebase项目配置

    • 确认Firebase项目中已添加Expo应用的Android SHA-1指纹(可通过expo fetch:android:hashes获取)。
    • 验证app.json中Firebase的Android/iOS客户端ID配置正确。
  5. 版本兼容性调整
    @react-native-firebase v17对应Firebase SDK v9,但web版firebase包可能和RN版存在兼容性问题,建议完全使用@react-native-firebase系列包,移除firebase依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 11:37:45