How to include the document id in Firestore collection in Angular 5

不问归期 提交于 2019-11-29 22:13:20

问题


I have this function that gets all the posts and I want to get the id of the post any idea how to get the id of the post or How to include the id when I add the document to the collection

get_the_posts(){
    this.Post_collection = this.afs.collection('posts'); 
    return this.Posts = this.Post_collection.valueChanges();
}

That gives me this output:

[
   { name: 'post 1 name' description: 'post description'}, 
   { name: 'post 2 name' description: 'post description'},
   { name: 'post 3 name' description: 'post description'},
]

And i want this output

[
   { id: 'm9mggfJtClLCvqeQ', name: 'post 1 name' description: 'post description'}, 
   { id: 'm9mggfJtCldsadaf', name: 'post 2 name' description: 'post description'},
   { id: 'm9mggfJtCdsasavq', name: 'post 3 name' description: 'post description'},
]

回答1:


.valueChanges() returns only data without any meta data. you can use .snapshotChanges() for that

this.Post_collection = this.afs.collection('posts');
return this.Posts = this.Post_collection.snapshotChanges().map(actions => {
  return actions.map(a => {
    const data = a.payload.doc.data();
    const id = a.payload.doc.id;
    return { id, ...data };
  });
});

also import import { Observable } from 'rxjs/Observable';

For your second question how to add id when pushing data to firestore. try

//get id from firestore
    let id = this.afs.createId();

    this.post = {
      id:id,
      name:'name',
      description:'description'
    }

    this.afs.collection('posts').doc(id).set(this.post).then();

Now you can use .valueChanges() to get the data.




回答2:


I got so annoyed that there isn't a method for this, so I made one to share with everyone. Something this basic should be built into the the library itself.

getCollectionWithIDs(collection,key,comparison,value) {
    return this.afs.collection<any>(collection, ref => 
        ref.where(
            key, comparison, value
        )).snapshotChanges().pipe(
            map(actions => actions.map(a => {
            const data = a.payload.doc.data();
            const id = a.payload.doc.id;
            return { id, ...data };
        })))
}

Note that this.afs is type AngularFirestore that should be in the constructor.




回答3:


You can use RXJS pipelines, easy read

AllDrivers() {
    return this.collection.snapshotChanges().pipe(
      map(
        (action) => {
            return action.map( a => {
              return {...a.payload.doc.data(),
                id: a.payload.doc.id
              };
            });
        }
      ),
      take(1)
    );



回答4:


As of May, 10, 2019 you can now use:

valueChanges({idField?: string})

and pass in an optional field name that will contain the id of the document.

Such as in your original post:

get_the_posts(){
    this.Post_collection = this.afs.collection('posts'); 
    return this.Posts = this.Post_collection.valueChanges({ idField: 'id' }); 
}

This would indeed return your objects in your desired output.

From the Collections documentation:

Streaming collection data

There are multiple ways of streaming collection data from Firestore.

valueChanges({idField?: string})

What is it? - The current state of your collection. Returns an Observable of data as a synchronized array of JSON objects. All Snapshot metadata is stripped and just the document data is included. Optionally, you can pass an options object with an idField key containing a string. If provided, the returned JSON objects will include their document ID mapped to a property with the name provided by idField.

[Emphasis mine]



来源:https://stackoverflow.com/questions/47254978/how-to-include-the-document-id-in-firestore-collection-in-angular-5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!