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

后端 未结 6 1088
温柔的废话
温柔的废话 2021-01-02 11:28

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

相关标签:
6条回答
  • 2021-01-02 11:35

    You could use the js spread operator and put that inside the query snapshot so using a bit of your code...

        async get_the_posts(){
            this.Post_collection = this.afs.collection('posts'); 
            return this.Posts = await this.Post_collection.onSnapshot(querySnapshot =>{
                            let arr = []
                            querySnapshot.forEach(function (doc) {
                                arr.push({id:doc.id, ...doc.data()});
    
                            });
                            return arr
            })
        }
    
    0 讨论(0)
  • 2021-01-02 11:41

    In my case, because I only want to get the data without subscribing to it, I'm adding the id in the then:

    **If you want the data in a different object: **

    await this.$fireStore
        .collection('SOME_COLLECTION')
        .doc('SOME_ID')
        .get()
        .then((item) => ({ id: item.id, data: item.data() }))
    

    **If you want the data spread in the returned object: **

    await this.$fireStore
        .collection('SOME_COLLECTION')
        .doc('SOME_ID')
        .get()
        .then((item) => ({ id: item.id, ...item.data() }))
    
    0 讨论(0)
  • 2021-01-02 11:43

    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]

    0 讨论(0)
  • 2021-01-02 11:44

    .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.

    0 讨论(0)
  • 2021-01-02 11:49

    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.

    0 讨论(0)
  • 2021-01-02 11:50

    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)
        );
    
    0 讨论(0)
提交回复
热议问题