【问题标题】:How to include the document id in Firestore collection in Angular 5如何在 Angular 5 的 Firestore 集合中包含文档 ID
【发布时间】:2018-04-25 13:59:56
【问题描述】:

我有这个函数可以获取所有帖子,我想获取帖子的 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'},
]

【问题讨论】:

    标签: angularfire2 google-cloud-firestore


    【解决方案1】:

    .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() 获取数据。

    【讨论】:

    • 为什么不直接做.valueChanges({ idField: 'id' });
    • 哦.. 刚刚看到你回答的日期:D
    • 这对我不起作用。当我使用 idfield 选项,并且想要 console.log(project.id) 它时,没有任何价值
    【解决方案2】:

    你可以使用 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】:

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

      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】:

      自 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 键的选项对象,该键包含一个字符串。如果提供,则返回的 JSON 对象将包含其文档 ID,该文档 ID 映射到具有 idField 提供的名称的属性。

      [强调我的]

      【讨论】:

      • 这对我不起作用。当我使用 idfield 选项,并且想要 console.log(project.id) 它时,没有任何价值
      【解决方案5】:

      您可以使用 js 扩展运算符并将其放在查询快照中 所以使用你的一些代码......

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

      【讨论】:

        【解决方案6】:

        就我而言,因为我只想获取数据而不订阅它,所以我在 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() }))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-05-11
          • 2021-06-10
          • 2019-09-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-02-20
          相关资源
          最近更新 更多