【问题标题】:How to retrieve document id's for collections in AngularFire2's Firestore如何在 AngularFire2 的 Firestore 中检索集合的文档 ID
【发布时间】:2018-07-14 07:03:38
【问题描述】:

我已经阅读了 Angularfirestores 文档,我觉得文档没有很好的记录,所以我有这个问题需要解决,我正在尝试从我的 firestore 中获取每个文档的唯一 ID。 这是我的sn-p:

private businessCollection2: AngularFirestoreCollection<Ibusiness>;
businesses2: Observable<any>;

this.businessCollection2 = this.fb.collection('businesses');
this.businesses2 = this.businessCollection2.snapshotChanges();

this.businesses2.pipe(
       map(
         changes => {
       const data = changes.payload.data();
       const id = changes.payload.id;
       return {id, ...data};
    })).subscribe(changes => {
      console.log(changes.id);
    });

我的浏览器控制台出现错误提示:

ERROR TypeError: Cannot read property 'data' of undefined
    at MapSubscriber.eval [as project] (app.component.ts:63)
    at MapSubscriber._next (map.js:35)
    at MapSubscriber.Subscriber.next (Subscriber.js:54)
    at eval (angularfire2.js:36)
    at ZoneDelegate.invoke (zone.js:388)
    at Object.onInvoke (core.js:4760)
    at ZoneDelegate.invoke (zone.js:387)
    at Zone.run (zone.js:138)
    at NgZone.run (core.js:4577)
    at SafeSubscriber.eval [as _next] (angularfire2.js:36)

我怀疑使用 data() 或其他问题存在问题。

【问题讨论】:

    标签: angular angularfire2 uniqueidentifier


    【解决方案1】:

    在大量文档、博客、教程和 stackoverflow 之间跳转后,我选择了适合我的通用服务。您所要做的就是指定一个路径,然后您就可以订阅生成的 Observable。

    我将假设您的组件结构如下:

    • 我的组件(文件夹)

      • myComponent.component.ts

      • myComponent.module.ts

      • firestore.service.ts

    firestore.service.ts(这个很长。)

    import { Injectable } from '@angular/core';
    import { AngularFirestore, AngularFirestoreCollection, 
    AngularFirestoreDocument } from '@angular/fire/firestore';
    import { FirebaseError } from 'firebase';
    import { Observable } from 'rxjs';
    import { map } from 'rxjs/operators';
    
    @Injectable({
      providedIn: 'root'
    })
       export class FirestoreService { 
    
       constructor(
        private db: AngularFirestore
       ) {
    
       }
    
    
     getCollectionRef(path: string, sortBy?: string): 
      AngularFirestoreCollection {
        if (sortBy === undefined) {
          return this.db.collection(path);
        } else {
          return this.db.collection(path, ref => ref.orderBy(sortBy));
        }
      }
    
      getDocumentRef(path: string): AngularFirestoreDocument {
        return this.db.doc(path);
      }
    
      getCollectionSnapshot(
        path: string,
        sortBy?: string
      ): Observable<any[]> {
        return this.getCollectionRef(path, sortBy).snapshotChanges();
      }
    
       getDocumentSnapshot(
        path: string,
      ): Observable<any> {
        return this.getDocumentRef(path).snapshotChanges();
      }
    
      getCollectionValue(
        path: string,
        sortBy?: string
      ): Observable<any[]> {
        return this.getCollectionRef(path, sortBy).valueChanges();
      }
    
      getDocumentValue(
        path: string,
      ): Observable<any> {
        return this.getDocumentRef(path).valueChanges();
      }
    
      getDocument(path: string): Observable<any> {
        return this.getDocumentSnapshot(path).pipe(
          map(changes => {
            const data = changes.payload.data();
            const id = changes.payload.id;
            return { id, ...data };
          })
        );
      }
    
      getCollection(path: string, sortBy?: string): Observable<any[]> {
        return this.getCollectionSnapshot(path, sortBy).pipe(
          map(changes => {
            return changes.map(change => {
              const data = change.payload.doc.data();
              const id = change.payload.doc.id;
              return { id, ...data };
            });
          }
          ));
    
      }
    
      createDocument(path: string, data: object):
      Promise<any | FirebaseError> {
        return this.getDocumentRef(path).set(data)
        .then(() => {
          return null;
        })
        .catch((error: FirebaseError) => {
          return error;
        });
      }
    
      updateDocument(path: string, data: object):
      Promise<any | FirebaseError> {
        return this.getDocumentRef(path).update(data)
        .then(() => {
          return null;
        })
        .catch((error: FirebaseError) => {
          return error;
        });
      }
    
      deleteDocument(path: string):
       Promise<any | FirebaseError> {
        return this.getDocumentRef(path).delete()
        .then(() => {
          return null;
        })
        .catch((error: FirebaseError) => {
          return error;
        });
      }
    
      createCollectionItem(path: string, data: object):
       Promise<any | FirebaseError> {
        return this.getCollectionRef(path).add(data)
        .then(() => {
          return null;
        })
        .catch((error: FirebaseError) => {
          return error;
        });
      }
    
    
     }
    

    myComponent.module.ts

    import { NgModule } from '@angular/core';
    import { CommonModule } from '@angular/common';
    import { FirestoreService } from './firestore.service';
    import { MyComponent } from './myComponent.component';
    
    
    @NgModule({
      imports: [
        CommonModule
      ],
      declarations: [MyComponent],
      providers: [
       FirestoreService,
      ]
    })
    export class MyComponentModule { }
    

    myComponent.component.ts

    import { Component, OnInit } from '@angular/core';
    import { FirestoreService } from './firestore.service';
    import { User } from 'firebase/app';
    import { Observable } from 'rxjs';
    
    @Component({
      selector: 'app-myComponent', // remember to change prefix 'app' to the one that your app uses.
      templateUrl: './myComponent.component.html',
      styleUrls: ['./myComponent.component.css']
    })
      export class MyComponentComponent implements OnInit {
        firestoreData: Observable<any[]>;
        dataPath = 'path/';
    
      constructor(
        private firestore: FirestoreService
      ) {
    
      }
    
      ngOnInit() {
    
      this.firestoreData = this.firestore.getCollection(this.dataPath);
    
        this.firestoreData.subscribe(firestoreData => {
          console.log(firestoreData);
          console.log(firestoreData[0].id);
          // in the template you can use *ngFor="let business of businesses | async"
        } );
    
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-09
      相关资源
      最近更新 更多