如何在Angular 5中的Firestore集合中包含文档ID

时间:2017-11-12 23:01:35

标签: angularfire2 google-cloud-firestore

我有这个功能获取所有帖子,我想得到帖子的ID 任何想法如何获取帖子的ID或如何在我将文档添加到集合

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

这给了我这个输出:

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

我想要这个输出

[
   { 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'},
]

6 个答案:

答案 0 :(得分:9)

.valueChanges()仅返回没有任何元数据的数据。您可以.snapshotChanges()使用

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 };
  });
});

还导入import { Observable } from 'rxjs/Observable';

关于第二个问题,如何在将数据推送到firestore时添加id。尝试

//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();

现在,您可以使用.valueChanges()来获取数据。

答案 1 :(得分:3)

截至2019年5月10日,您现在可以使用:

valueChanges({idField?: string})

并传入一个可选的字段名称,其中将包含文档的ID。

例如您的原始帖子:

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

这确实会在所需的输出中返回对象。

来自Collections documentation

  

流式收集数据

     

有多种方法可以从Firestore流式传输收集数据。

     

valueChanges({idField ?: string})

     

是什么? -您收藏的当前状态。返回一个Observable数据作为JSON对象的同步数组。删除了所有快照元数据,仅包含文档数据。 (可选)您可以传递一个带有包含字符串的idField键的options对象。如果提供的话,返回的JSON对象将包括其文档ID,该ID映射到idField提供的名称的属性。

[重点突出]

答案 2 :(得分:0)

您可以使用RXJS管道,易于阅读

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

答案 3 :(得分:0)

我很生气,没有办法解决这个问题,所以我与所有人分享了一个方法。这个基本的东西应该内置到库本身中。

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 };
        })))
}

请注意,this.afs是AngularFirestore类型,应该在构造函数中。

答案 4 :(得分:0)

您可以使用js spread运算符并将其放在查询快照中 因此,请使用您的一些代码...

    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
        })
    }

答案 5 :(得分:0)

在我的情况下,因为我只想获取数据而不订阅数据,所以我在then中添加了ID:

**如果要将数据存储在其他对象中:**

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

**如果您希望数据散布在返回的对象中:**

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