Firestore Получение идентификатора документов из коллекции

Я пытаюсь получить свои документы с идентификатором, но не могу его понять.
В настоящее время я получаю свои документы следующим образом:

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

Я отлично получаю список документов, но у них нет идентификатора документа.

Как я могу получить его для каждого документа?


person DominikG    schedule 24.10.2017    source источник
comment
Я застрял на этом. Надеюсь, мы что-то получим .. скрестим пальцы, переполнение стека   -  person Mustafa    schedule 24.10.2017
comment
На ванили делаю карту doc => {...doc.data(), id: doc.id}. Вы можете использовать оператор карты, чтобы добиться того же на RX.   -  person Victor Nascimento    schedule 24.10.2017
comment
Собственно, из их документов: github.com/angular/angularfire2/ blob / master / docs / firestore /   -  person Victor Nascimento    schedule 24.10.2017


Ответы (9)


Для angular 8 и Firebase 6 вы можете использовать поле идентификатора параметра

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

это добавляет идентификатор документа к объекту с указанным ключом (customIdName)

person Ivan Tarskich    schedule 07.07.2019
comment
Примечание: это работает со ссылкой на коллекцию, но не со ссылкой на документ ... - person Jonathan; 25.04.2020
comment
просто и красиво - person Savas Karaduman; 12.06.2021

Чтобы получить идентификатор документов в коллекции, вы должны использовать 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

person Luis Ruiz Figueroa    schedule 13.11.2017
comment
Некоторое время я пытался скомпилировать свой код. Мой вопрос: this.shirts - это Observable ‹ShirtId []›. Пример возвращает '{id, ... data}', который не является объектом типа ShirtId. Как он преобразуется в тип ShirtId, это просто объект. - person flobacca; 11.05.2018
comment
Привет, спасибо за ответ, у меня была такая же проблема. У меня есть еще один вопрос, данные из документов также извлекаются? Я имею в виду разумную производительность, если мне просто нужны идентификаторы без извлечения данных документа, следует ли мне использовать это решение? - person Lambasoft; 10.02.2019
comment
@Lambasoft да с const data = a.payload.doc.data () as Shirt; объект восстанавливается - person Luis Ruiz Figueroa; 11.02.2019
comment
@LuisRuizFigueroa Спасибо за ответ! Поэтому, если я не вызываю doc.data (), объект не будет восстановлен, и я могу использовать его id normall - person Lambasoft; 11.02.2019
comment
В более новой версии RXJS вам нужно будет написать snapshotChanges (). Pipe (map (actions = ›... Надеюсь, это поможет всем, кто смотрит на этот пост из будущего :) - person Cooper Scott; 28.05.2019

Наконец-то я нашел решение. Виктор был близок с данными документа.

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 () не включает метаданные, поэтому мы должны использовать SnapshotChanges (), когда нам требуется идентификатор документа, а затем правильно сопоставить его, как указано здесь https://github.com/angular/angularfire2/blob/master/docs/firestore/collections.md

person DominikG    schedule 25.10.2017
comment
Насколько я понял ваш вопрос, вы хотите получить id после сохранения? или вы хотите получить идентификатор каждого документа в коллекции? - person Luis Ruiz Figueroa; 14.11.2017
comment
Работает. Изменил его на следующее, чтобы немного очистить его: `` this.items = db.collection ('games'). SnapshotChanges (). Pipe (map (actions = ›actions.map (a =› {return {gameId: a.payload.doc.id, ... a.payload.doc.data ()};}))); `` '' - person cgatian; 04.01.2019

Для 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 };
        });
        })
    );
person phicon    schedule 25.05.2018

doc.id получает UID.

Совместите с остальными данными для одного объекта следующим образом:

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

person corysimmons    schedule 26.01.2018
comment
Этот! И это задокументировано для интерфейса DocumentSnaphot (в сборник действительно QueryDocumentSnaphot, который расширяет DocumentSnaphot) - person Саша Давиденко; 13.03.2019
comment
Это кажется интересным подходом, однако ссылка не предлагает никаких примеров использования, и этот ответ: давайте не будем достаточно самодостаточными. - person KhoPhi; 24.03.2019

Поскольку вы используете angularFire, нет никакого смысла возвращаться к методам firebase по умолчанию для вашей реализации. В самом AngularFire реализованы соответствующие механизмы. Просто надо использовать это.

valueChanges() метод angularFire предоставляет перегрузку для получения идентификатора каждого документа коллекции путем простого добавления объекта в качестве параметра к методу.

valueChanges({ idField: 'id' })

Здесь idField должно быть таким же, как есть. 'id' может быть любым, как вы хотите, чтобы назывался ваш идентификатор документа.

Тогда каждый объект документа в возвращаемом массиве будет выглядеть следующим образом.

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

Затем вы можете легко получить идентификатор документа, обратившись к названному вами полю.

AngularFire 5.2.0

person Hasintha Abeykoon    schedule 24.01.2020

Можно получить ID перед добавлением документов в базу данных:

var idBefore =  this.afs.createId();
console.log(idBefore);
person Diego Venâncio    schedule 06.11.2017
comment
Обеспечит ли этот метод уникальный идентификатор и предотвратит ли конфликт идентификаторов? - person Pini Cheyni; 18.04.2018
comment
Точно. @Pini Cheyni - person Diego Venâncio; 18.04.2018

Для ссылок на документы, а не на коллекции, вам понадобятся:

// 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'}); здесь работать не будет. Я предполагаю, что это не было реализовано, поскольку обычно вы ищете документ по идентификатору ...

person Jonathan    schedule 25.04.2020
comment
Я могу получить все данные и идентификатор, но эта функция распространения не работает. Это потому, что у меня есть массивы в моем объекте (данные документа)? - person O-9; 13.08.2020

Я пробовал это

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;
            });
          })
        );
person Trilok Singh    schedule 14.05.2020