【问题标题】:Firestore Getting documents id from collectionFirestore 从集合中获取文档 ID
【发布时间】:2018-04-04 15:43:21
【问题描述】:

我正在尝试使用 id 检索我的文档,但无法弄清楚。
目前我这样检索我的文件:

const racesCollection: AngularFirestoreCollection<Races> = this.afs.collection('races');
return racesCollection.valueChanges();

我确实得到了我的文档列表,但是没有文档 ID。

如何为每个文档检索它?

【问题讨论】:

  • 我坚持这一点。希望我们能得到一些东西.. 手指交叉堆栈溢出
  • 在香草上,我正在制作doc =&gt; {...doc.data(), id: doc.id} 的地图。您可以使用 map 运算符在 RX 上实现相同的效果。

标签: angular firebase google-cloud-firestore nosql angularfire2


【解决方案1】:

对于 angular 8 和 Firebase 6,您可以使用选项 id 字段

      getAllDocs() {
           const ref = this.db.collection('items');
           return ref.valueChanges({idField: 'customIdName'});
      }

这会将文档的 ID 添加到具有指定键 (customIdName) 的对象上

【讨论】:

  • 注意:这适用于集合引用,但不适用于文档引用...
  • 简单漂亮
【解决方案2】:

要获取集合中文档的id,必须使用snapshotChanges()

    this.shirtCollection = afs.collection<Shirt>('shirts');
    // .snapshotChanges() returns a DocumentChangeAction[], which contains
    // a lot of information about "what happened" with each change. If you want to
    // get the data and the id use the map operator.
    this.shirts = this.shirtCollection.snapshotChanges().map(actions => {
      return actions.map(a => {
        const data = a.payload.doc.data() as Shirt;
        const id = a.payload.doc.id;
        return { id, ...data };
      });
    });

文档 https://github.com/angular/angularfire2/blob/7eb3e51022c7381dfc94ffb9e12555065f060639/docs/firestore/collections.md#example

【讨论】:

  • 我已经尝试了一段时间来编译我的代码。我的问题是 this.shirts 是一个 Observable。该示例返回“{id, ...data}”,它不是 ShirtId 类型的对象。怎么转成 ShirtId 类型的,它只是一个对象。
  • 您好,谢谢您的回答,我也遇到了同样的问题。我还有一个问题,是否也获取了文档数据?我的意思是性能方面,如果我只想要 id 而不获取文档数据,我应该使用这个解决方案吗?
  • @Lambasoft 是,const data = a.payload.doc.data () as Shirt; 正在恢复对象
  • @LuisRuizFigueroa 感谢您的回复!所以如果我不调用 doc.data() 对象将不会被恢复,我可以使用它的 id normall
  • 使用较新的 RXJS,您需要编写 snapshotChanges().pipe(map(actions => ... 希望对以后看到这篇文章的每个人有所帮助:)
【解决方案3】:

我终于找到了解决办法。 Victor 非常了解文档数据。

const racesCollection: AngularFirestoreCollection<Race>;
return racesCollection.snapshotChanges().map(actions => {       
  return actions.map(a => {
    const data = a.payload.doc.data() as Race;
    data.id = a.payload.doc.id;
    return data;
  });
});

ValueChanges() 不包含元数据,因此我们必须在需要文档 ID 时使用 SnapshotChanges(),然后按此处所述正确映射它https://github.com/angular/angularfire2/blob/master/docs/firestore/collections.md

【讨论】:

  • 我理解你的问题,你想保存后获取id吗?还是要获取集合中每个文档的 id?
  • 有效。将其更改为以下内容以稍微清理一下 ``` this.items = db.collection('games').snapshotChanges().pipe( map(actions => actions.map(a => { return { gameId: a.payload.doc.id, ...a.payload.doc.data() }; })) ); ```
【解决方案4】:

对于 angular6+

    this.shirtCollection = afs.collection<Shirt>('shirts');
    this.shirts = this.shirtCollection.snapshotChanges().pipe(
        map(actions => {
        return actions.map(a => {
            const data = a.payload.doc.data() as Shirt;
            const id = a.payload.doc.id;
            return { id, ...data };
        });
        })
    );

【讨论】:

    【解决方案5】:

    doc.id 获取 UID。

    像这样结合一个对象的其余数据:

    Object.assign({ uid: doc.id }, doc.data())

    【讨论】:

    • 这个!它记录在DocumentSnaphot interface 中(在一个集合中,它确实是扩展DocumentSnaphotQueryDocumentSnaphot
    • 这似乎是一个有趣的方法,但是,该链接没有提供任何使用示例,这个答案是,让我们不够自我维持
    【解决方案6】:

    由于您使用的是 angularFire,因此如果您要为您的实现返回默认的 firebase 方法是没有任何意义的。 AngularFire 本身已经实现了适当的机制。只需要使用它。

    angularFire 的

    valueChanges() 方法提供了一个重载,通过简单地将对象作为参数添加到该方法中来获取集合中每个文档的ID。

    valueChanges({ idField: 'id' })
    

    这里的 'idField' 必须和原来的一样。 'id' 可以是您希望调用文档 ID 的任何内容。

    那么返回数组上的每个文档对象会是这个样子。

    {
      field1 = <field1 value>,
      field2 = <field2 value>,
      ..
      id = 'whatEverTheDocumentIdWas'
    }
    

    然后您可以通过引用您命名的字段轻松获取文档ID。

    AngularFire 5.2.0

    【讨论】:

      【解决方案7】:

      在数据库中添加文档之前可以获取ID:

      var idBefore =  this.afs.createId();
      console.log(idBefore);
      

      【讨论】:

      • 这种方法能保证ID唯一性,防止ID冲突吗?
      • 没错。 @Pini Cheyni
      【解决方案8】:

      对于文档引用,而不是集合,您需要:

      // when you know the 'id'
      
      this.afs.doc(`items/${id}`)
        .snapshotChanges().pipe(
          map((doc: any) => {
            const data = doc.payload.data();
            const id = doc.payload.id;
            return { id, ...data };
          });
      

      .valueChanges({ idField: 'id'}); 在这里不起作用。我认为它没有实现,因为通常您通过 id 搜索文档...

      【讨论】:

      • 我可以得到所有的数据和id,但是那个传播的东西不起作用。是因为我的(文档数据)对象中有数组吗?
      【解决方案9】:

      我试过了

      return this.db.collection('items').snapshotChanges().pipe(
                map(actions => {       
                  return actions.map(a => {
                    const data = a.payload.doc.data() as Item;
                    data.id = a.payload.doc.id;
                    data.$key = a.payload.doc.id;
                    return data;
                  });
                })
              );
      

      【讨论】:

        猜你喜欢
        • 2021-12-16
        • 2019-09-17
        • 1970-01-01
        • 2020-12-27
        • 2021-07-17
        • 1970-01-01
        • 2022-07-08
        • 2019-09-24
        • 1970-01-01
        相关资源
        最近更新 更多