Reputation: 1361
I'm trying to retrieve my documents with id but can't figure it out.
Currently I retrieve my documents like this :
const racesCollection: AngularFirestoreCollection<Races> = this.afs.collection('races');
return racesCollection.valueChanges();
I do get my documents list perfectly, however there is no doc id with them.
How can I retrieve it for each document ?
Upvotes: 77
Views: 185826
Reputation: 1386
Here are my implementations with Angular 17 and Firestore modular API.
function getAllDestinations() {
return defer(() =>
from(getDocs(query(collection(getFirestore(), 'countries'))))
);
}
function fetchDestinations(
fetchMethod: () => Observable<QuerySnapshot<DocumentData, DocumentData>>
): Observable<Destination[]> {
return fetchMethod().pipe(
switchMap((documents) => {
const data = documents.docs.map((doc) => {
return { ...doc.data(), id: doc.id }; // <-- include the document id
}) as Destination[];
// ... other details
})
);
}
// usage
fetchDestinations(() => getAllDestinations()).pipe(
tap(data: Destination) => {/* deal with data */}
).subscribe()
Upvotes: 0
Reputation: 10502
Sadly, in React Native
environment, I couldn't find a way to import doc
, to get the id
. I'm working with https://rnfirebase.io/firestore/usage. It can be the same case for some less common environments relying on Firebase
plugin/libraries.
In that case console.log(documentSnapshot.ref);
will return you what you can find below.
as you could see, while working with the raw
response, it can be accessed via documentSnapshot.ref._documentPath._parts[1]
. documentSnapshot
is of course part of querySnapshot
.
Upvotes: 0
Reputation: 3617
For 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 };
});
})
);
Upvotes: 38
Reputation: 2577
To obtain the id of the documents in a collection, you must use 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 };
});
});
Documentation https://github.com/angular/angularfire2/blob/7eb3e51022c7381dfc94ffb9e12555065f060639/docs/firestore/collections.md#example
Upvotes: 52
Reputation: 1353
I have tried this
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;
});
})
);
Upvotes: 0
Reputation: 4689
For document references, not collections, you need:
// 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 };
});
as .valueChanges({ idField: 'id'});
will not work here. I assume it was not implemented since generally you search for a document by the id...
Upvotes: 3
Reputation: 524
Since you are using angularFire, it doesn't make any sense if you are going back to default firebase methods for your implementation. AngularFire itself has the proper mechanisms implemented. Just have to use it.
valueChanges()
method of angularFire provides an overload for getting the ID of each document of the collection by simply adding a object as a parameter to the method.
valueChanges({ idField: 'id' })
Here 'idField' must be same as it is. 'id' can be anything that you want your document IDs to be called.
Then the each document object on the returned array will look like this.
{
field1 = <field1 value>,
field2 = <field2 value>,
..
id = 'whatEverTheDocumentIdWas'
}
Then you can easily get the document ID by referencing to the field that you named.
AngularFire 5.2.0
Upvotes: 20
Reputation: 1527
For angular 8 and Firebase 6 you can use the option id field
getAllDocs() {
const ref = this.db.collection('items');
return ref.valueChanges({idField: 'customIdName'});
}
this adds the Id of the document on the object with a specified key (customIdName)
Upvotes: 70
Reputation: 7675
doc.id
gets the UID.
Combine with the rest of the data for one object like so:
Object.assign({ uid: doc.id }, doc.data())
Upvotes: 26
Reputation: 6007
Can get ID before add documents in database:
var idBefore = this.afs.createId();
console.log(idBefore);
Upvotes: 3
Reputation: 1361
I've finally found the solution. Victor was close with the doc data.
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() doesn't include metadata, therefor we must use SnapshotChanges() when we require the document id and then map it properly as stated here https://github.com/angular/angularfire2/blob/master/docs/firestore/collections.md
Upvotes: 44