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

Firebase Firestore规则阻止已认证用户访问数据的问题排查

解决Firebase Firestore「Missing or insufficient permissions」权限错误

问题概述

React Native项目使用Firebase Firestore存储核心数据,调整安全规则后出现权限拒绝错误,无法满足App Store上架要求。具体需求:

  • ConnectWithAgent、GeneralConnect、SellMyHome、ShowingTour四个集合:允许所有人读写
  • Favorites、Feed、Offers、Profiles、RecentViews五个集合:允许所有人写入,仅已登录认证用户可读(其中Favorites、Profiles、RecentViews需限制用户仅能访问自身userId匹配的文档)

已登录测试用户读取自身Favorites文档时触发以下错误:

ERROR  [2023-06-26T17:59:41.457Z]  @firebase/firestore: Firestore (9.21.0): 
Uncaught Error in snapshot listener: FirebaseError: 
[code=permission-denied]: Missing or insufficient permissions.

修正后的安全规则

根据需求,针对不同集合设置精准权限,同时对用户专属文档添加用户uid匹配验证,完整规则代码如下:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // 开放全权限的4个集合
    match /ConnectWithAgent/{document=**} {
      allow read, write: if true;
    }
    match /GeneralConnect/{document=**} {
      allow read, write: if true;
    }
    match /SellMyHome/{document=**} {
      allow read, write: if true;
    }
    match /ShowingTour/{document=**} {
      allow read, write: if true;
    }

    // 用户专属文档集合:所有人可写,仅登录用户可读取自身文档
    match /Favorites/{docId} {
      allow write: if true;
      allow read: if request.auth != null && resource.data.userId == request.auth.uid;
    }
    match /Profiles/{docId} {
      allow write: if true;
      allow read: if request.auth != null && resource.data.userId == request.auth.uid;
    }
    match /RecentViews/{docId} {
      allow write: if true;
      allow read: if request.auth != null && resource.data.userId == request.auth.uid;
    }

    // 开放给所有登录用户读取的集合:所有人可写,任意登录用户可读
    match /Feed/{document=**} {
      allow write: if true;
      allow read: if request.auth != null;
    }
    match /Offers/{document=**} {
      allow write: if true;
      allow read: if request.auth != null;
    }
  }
}

读取逻辑校验

确保读取代码正确获取用户uid并匹配文档字段,以下是Firebase v9的示例实现:

import { getAuth, onAuthStateChanged } from "firebase/auth";
import { collection, query, where, onSnapshot } from "firebase/firestore";
import { db } from "../path/to/firebaseConfig";

// 监听用户收藏数据(确保在用户登录后执行)
const setupFavoritesListener = () => {
  const auth = getAuth();
  
  onAuthStateChanged(auth, (user) => {
    if (!user) {
      console.log("用户未登录,无法读取收藏");
      return;
    }

    const q = query(collection(db, "Favorites"), where("userId", "==", user.uid));
    
    onSnapshot(q, (snapshot) => {
      const favorites = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
      console.log("更新收藏数据", favorites);
      // 处理数据更新逻辑
    }, (error) => {
      console.error("监听收藏失败", error);
    });
  });
};

关键检查点

  1. 文档字段一致性:确认Favorites等集合的文档中存在userId字段,且值与用户uid完全匹配(注意大小写)
  2. 登录状态时机:通过onAuthStateChanged监听用户登录状态,确保读取/监听操作在用户认证完成后执行
  3. 查询条件准确性:查询必须包含userId == user.uid的条件,否则会触发权限规则拦截

调试方法

  • 使用Firebase控制台的规则模拟器:模拟已登录用户读取自身文档的场景,验证规则是否生效
  • 打印用户uid与文档userId:在读取前输出两者的值,确认是否一致
  • 检查Auth状态:确保用户读取数据时处于已登录状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 20:52:46