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

Firebase/Firestore安全规则失效及resource未定义问题求助

Firestore安全规则问题解决指南

错误原因分析

你遇到的resource is undefined错误,核心原因是集合级别的list查询(比如collection.get())中不存在resource对象:

  • resource仅在单个文档操作(如获取单个文档、更新、删除)时可用,代表目标文档的当前数据;
  • 批量读取集合时,Firestore规则无法提前获取每个文档的resource,因此直接引用会触发未定义错误。

同时,你当前的方案存在致命安全漏洞:未使用Firebase认证,导致安全规则无法可靠识别请求发起者的身份——任何人只要知道其他用户的username,就能构造请求访问其数据,完全无法实现“用户仅能读写自己的progress集合”的需求。

推荐解决方案:使用Firebase自定义认证

这是生产环境下的标准安全方案,通过自定义认证关联用户身份,让规则能精准识别操作主体:

1. 编写云函数验证用户名密码并生成自定义Token

创建云函数,负责验证用户输入的用户名密码,通过后生成Firebase自定义认证Token:

const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();

exports.login = functions.https.onCall(async (data, context) => {
  const { username, password } = data;
  // 查询匹配的用户文档
  const userSnapshot = await admin.firestore()
    .collection("users")
    .where("username", "==", username)
    .where("password", "==", password)
    .get();

  if (userSnapshot.empty) {
    throw new functions.https.HttpsError("invalid-argument", "用户名或密码错误");
  }

  const userDoc = userSnapshot.docs[0];
  // 生成自定义Token,用用户文档ID作为Auth的uid
  const token = await admin.auth().createCustomToken(userDoc.id);
  return { token, userId: userDoc.id };
});

2. 客户端通过云函数登录

在Ionic/Angular客户端调用云函数获取Token,完成Firebase认证:

import { AngularFireAuth } from '@angular/fire/compat/auth';
import { Functions, httpsCallable } from '@angular/fire/functions';

constructor(private afAuth: AngularFireAuth, private functions: Functions) {}

async login(username: string, password: string) {
  const loginFn = httpsCallable(this.functions, 'login');
  const result = await loginFn({ username, password });
  const { token } = result.data as { token: string };
  // 用自定义Token完成登录
  await this.afAuth.signInWithCustomToken(token);
}

3. 设置安全规则

现在可以通过request.auth.uid识别用户身份,精准控制数据访问权限:

service cloud.firestore {
  match /databases/{database}/documents {
    // 仅允许用户读取自己的用户文档
    match /users/{userId} {
      allow read: if request.auth.uid == userId;
      // 禁止直接写入用户文档(避免篡改敏感信息,如需修改可通过云函数)
      allow write: if false;
    }

    // 允许用户读写自己的progress子集合
    match /users/{userId}/progress/{progressDoc} {
      allow read, write: if request.auth.uid == userId;
    }
  }
}

测试用临时方案(不安全,仅用于本地调试)

如果暂时不想引入云函数,可临时开放符合查询条件的读取权限,但请注意这会导致用户数据暴露风险:

service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userDoc} {
      // 仅允许携带username和deployment条件的查询
      allow read: if request.query.where('username', '==', resource.data.username) 
        && request.query.where('deployment', '==', resource.data.deployment);
      allow write: if false;
    }

    // 临时开放progress子集合权限(测试用)
    match /users/{userDoc}/progress/{progressDoc} {
      allow read, write: if true;
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 02:50:27