Angular项目中TypeScript读取Firestore数据失败问题求助
一、库选择建议:优先用模块化API
当前AngularFire推荐使用模块化API(从@angular/fire/firestore导入的方法),compat包(如AngularFirestore)仅用于旧项目迁移,新项目直接用模块化API即可——它支持树摇优化,打包体积更小,且和Firebase Web SDK v9+的原生API完全对齐。
你可以直接移除服务中的AngularFirestore依赖,只保留Firestore注入。
二、获取数据失败的核心问题
你的代码里有两个关键错误:
- 文档ID匹配错误:在
rejectFriendRequest中用了JSON.stringify(currentUser),如果currentUser本身是字符串(比如邮箱),这会把ID变成带引号的格式(例如"user@example.com"),但控制台里的文档ID是不带引号的原始邮箱,导致后续获取时ID不匹配。 - 不必要的异步操作:
doc(colRef, id)是同步方法,不需要加await。
三、修正后的代码示例
1. 精简FirestoreService
import { Injectable } from '@angular/core'; import { Firestore, doc, getDoc, docData, updateDoc, arrayRemove, arrayUnion } from '@angular/fire/firestore'; import { Observable } from 'rxjs'; import { ProfileUser } from '../model/profile-user'; @Injectable({ providedIn: 'root' }) export class FirestoreService { constructor(private firestore: Firestore) {} // 修正更新方法:移除JSON.stringify async rejectFriendRequest(rejectedUser: string, currentUser: string) { const recipientRef = doc(this.firestore, 'users', currentUser); await updateDoc(recipientRef, { invitationsFrom: arrayRemove(rejectedUser), rejectedInvitation: arrayUnion(rejectedUser) }); } // 方式1:用Promise获取数据(适合单次查询) async getUser(id: string): Promise<ProfileUser | null> { const docRef = doc(this.firestore, 'users', id); const docSnap = await getDoc(docRef); if (docSnap.exists()) { return docSnap.data() as ProfileUser; } else { console.log('目标文档不存在'); return null; } } // 方式2:用Observable获取数据(Angular响应式场景推荐) getUser$ (id: string): Observable<ProfileUser | null> { const docRef = doc(this.firestore, 'users', id); return docData(docRef) as Observable<ProfileUser | null>; } }
2. 组件中调用示例
import { Component, OnInit } from '@angular/core'; import { FirestoreService } from './services/firestore.service'; @Component({ selector: 'app-user', templateUrl: './user.component.html' }) export class UserComponent implements OnInit { constructor(private firestoreService: FirestoreService) {} ngOnInit() { const userId = 'user@example.com'; // 确保和Firestore控制台的文档ID完全一致 // 用Observable监听数据变化 this.firestoreService.getUser$(userId).subscribe(user => { if (user) { console.log('用户数据:', user); } }); // 或用Promise单次获取 this.firestoreService.getUser(userId).then(user => { console.log('单次获取用户:', user); }); } }
四、邮箱作为文档ID的注意事项
Firestore文档ID支持包含.,之前找不到文档不是因为.,而是错误地用JSON.stringify给邮箱加了引号。只要确保创建文档、更新文档、获取文档时用的是原始邮箱字符串,就不会有问题。
五、排查小技巧
- 打开Firestore控制台,确认目标文档的ID和你传入的
id完全一致(包括大小写、无多余符号); - 临时放宽Firestore规则(测试用):设置
allow read, write: if true;,排除权限问题; - 用
getDoc的方式可以明确判断文档是否存在,比直接订阅docData更方便排查问题。
内容的提问来源于stack exchange,提问作者Maczosss
相关产品推荐
相关产品推荐

