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

如何通过Angular/Fire访问Firestore非公开集合及登录后请求机制?

解决Firestore认证集合访问问题

前提场景

假设Firestore存在public和nonpublic两个集合,对应的安全规则如下:

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

在Angular/Fire中,请求public集合数据的代码如下:

import { Firestore, collection, collectionData } from '@angular/fire/firestore';
import { Observable } from 'rxjs';

@Component({/* 组件配置 */})
export class YourComponent {
  firestore: Firestore = inject(Firestore);
  items$: Observable<any[]>;

  constructor() {
    const publicCollection = collection(this.firestore, 'public');
    this.items$ = collectionData(publicCollection);
  }  
}

直接请求nonpublic集合会触发权限错误,需在用户注册登录后按以下方式处理:


1. 如何请求需要登录权限的集合?

用户通过registerUserWithPassword完成登录后,Angular/Fire会自动关联当前认证用户到Firestore请求中,你只需要确保在用户登录状态下发起请求即可。可以通过Auth服务的authState监听用户状态,避免在未登录时请求受限集合:

import { Firestore, collection, collectionData } from '@angular/fire/firestore';
import { Auth, authState } from '@angular/fire/auth';
import { Observable, switchMap } from 'rxjs';

@Component({/* 组件配置 */})
export class YourComponent {
  firestore: Firestore = inject(Firestore);
  auth: Auth = inject(Auth);
  nonPublicItems$: Observable<any[]>;

  constructor() {
    // 监听用户登录状态,仅当用户存在时请求nonpublic集合
    this.nonPublicItems$ = authState(this.auth).pipe(
      switchMap(user => {
        if (!user) {
          // 用户未登录时返回空数据流或自定义处理逻辑
          return new Observable(observer => observer.next([]));
        }
        const nonPublicCollection = collection(this.firestore, 'nonpublic');
        return collectionData(nonPublicCollection);
      })
    );
  }  
}

2. 如何使用该登录用户访问nonpublic集合?

Angular/Fire不需要手动将currentUser传递给collection方法(你提到的collection(this.firestore, 'nonpublic', currentUser)写法完全不必要)。Firebase Auth与Firestore深度集成,用户登录后,Firebase SDK会自动将用户的认证令牌附加到每一个Firestore请求中,Firestore后端会通过安全规则中的request.auth字段获取用户信息。

如果需要基于当前用户做更细粒度的权限控制(比如仅允许用户访问自己的文档),可以修改安全规则,同时在请求时指定用户ID路径:

// 假设nonpublic下有按用户ID划分的子集合
const userCollection = collection(this.firestore, `nonpublic/${user.uid}`);

对应的安全规则可调整为:

match /nonpublic/{userId}/{document=**} {
  allow read: if request.auth.uid == userId;
  allow write: if false;
}

3. 用户登录后Firestore请求的工作机制

  1. 认证令牌生成与存储:用户通过registerUserWithPassword登录成功后,Firebase Auth会在客户端生成短期有效的ID令牌(JWT),并存储在本地(浏览器的localStorage或IndexedDB)。
  2. 请求自动附加令牌:每次通过Angular/Fire发起Firestore请求时,底层Firebase SDK会自动取出当前用户的ID令牌,附加到请求的HTTP头中。
  3. 后端验证与规则校验:Firestore后端收到请求后,先验证ID令牌的有效性(包括签名、过期时间等),解析出用户认证信息(如uid、邮箱等),并注入到安全规则的request.auth对象中。
  4. 权限判断与响应:后端根据安全规则的条件(比如request.auth != null)判断是否允许该请求。条件满足则返回数据,否则返回权限错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 18:43:11