【发布时间】:2019-04-13 07:10:17
【问题描述】:
我有一个带有 firebase 应用程序的 angular 6 我有一个带有可观察对象的服务(我稍后希望多个订阅者收听同一个可观察对象) 还有一个订阅这个 observable 的组件 我试图实现的是获取 auth 对象,从中获取 userId (UID) 并在 db 中搜索具有此 id 的所有文档
组件在 ngOnInit 钩子上调用 observable,但在阶段它仍然为空,所以我得到 p>
无法读取未定义的属性“订阅”
问题是,如果我运行代码来填充订阅块内的 observable(以获取身份验证数据),我看不到数据,如果它在它之外(使用静态 UID 运行同步)比它确实填写正确并显示数据 这是服务的代码
import { Injectable, EventEmitter } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection, DocumentChangeAction } from '@angular/fire/firestore';
import { Expense } from '../model/Expense';
import { Observable, ReplaySubject, Subject, from } from 'rxjs';
import { map } from 'rxjs/operators';
import { AuthService } from '../core/services/auth.service';
@Injectable({
providedIn: 'root',
})
export class ExpenseService {
private dbPath = '/expenses';
expenseDetailEvent: EventEmitter<Expense> = new EventEmitter<Expense>();
expensesRef: AngularFirestoreCollection<Expense> = null;
expenses$: Observable<Expense[]>;
constructor(private db: AngularFirestore, auth: AuthService) {
auth.user$.subscribe(
user => {
this.expensesRef = this.db.collection<Expense>(this.dbPath, ref =>
ref.where('clientId', '==', user.uid)
);
this.expenses$ = this.expensesRef.snapshotChanges().pipe(
map(actions =>
actions.map(a => {
const data = a.payload.doc.data() as Expense;
const id = a.payload.doc.id;
return { id, ...data };
})
)
);
},
error => console.log(error)
);
}
createExpense(expense: Expense): Observable<any> {
return from(this.expensesRef.add(expense));
}
updateExpense(expense: Expense): Observable<any> {
return from(this.expensesRef.doc(expense.id).update(expense));
}
}
组件只是这样做
ngOnInit() {
this.expenseService.expenses$.subscribe(expenses => this.expenses = expenses);
}
我注意到网上所有的例子都在组件上调用了这个,但我觉得数据库调用应该在一个服务中,就像它使用普通的 http api 调用一样
更新 如果我像这样初始化服务
expenses$: Observable<Expense[]> = of([]);
所以应用程序当然不会崩溃,但我没有看到任何数据 如果我只是将代码拉到外面并使用静态 UID...(当然 user.uid 与我粘贴的静态字符串相同)
这是更新的代码
constructor(private db: AngularFirestore, auth: AuthService) {
console.log('being here ,i see the data on screen using the static uid');
this.expensesRef = this.db.collection<Expense>(this.dbPath, ref =>
ref.where('clientId', '==', 'noYVScDtKfNB5aFqRkAJR7ghxio2')
);
this.expenses$ = this.expensesRef.snapshotChanges().pipe(
map(actions =>
actions.map(a => {
const data = a.payload.doc.data() as Expense;
const id = a.payload.doc.id;
return { id, ...data };
})
)
);
auth.user$.subscribe(
user => {
console.log('if inside here than it will not show any data on screen');
},
error => console.log(error)
);
}
【问题讨论】:
-
你有没有尝试使用ngAfterViewInit()
-
我做了,没有效果,问题是observable在那之后被初始化了
标签: angular firebase google-cloud-firestore angular6