Reputation:
I have this function that gets all the posts and I want to get the id of the post any idea how to get the id of the post or How to include the id when I add the document to the collection
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'},
]
Upvotes: 12
Views: 12822
Reputation: 31
In my case, because I only want to get the data without subscribing to it, I'm adding the id in the then:
**If you want the data in a different object: **
await this.$fireStore
.collection('SOME_COLLECTION')
.doc('SOME_ID')
.get()
.then((item) => ({ id: item.id, data: item.data() }))
**If you want the data spread in the returned object: **
await this.$fireStore
.collection('SOME_COLLECTION')
.doc('SOME_ID')
.get()
.then((item) => ({ id: item.id, ...item.data() }))
Upvotes: 0
Reputation: 384
You could use the js spread operator and put that inside the query snapshot so using a bit of your code...
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
})
}
Upvotes: 0
Reputation: 1124
As of May, 10, 2019 you can now use:
valueChanges({idField?: string})
and pass in an optional field name that will contain the id of the document.
Such as in your original post:
get_the_posts(){
this.Post_collection = this.afs.collection('posts');
return this.Posts = this.Post_collection.valueChanges({ idField: 'id' });
}
This would indeed return your objects in your desired output.
From the Collections documentation:
Streaming collection data
There are multiple ways of streaming collection data from Firestore.
valueChanges({idField?: string})
What is it? - The current state of your collection. Returns an Observable of data as a synchronized array of JSON objects. All Snapshot metadata is stripped and just the document data is included. Optionally, you can pass an options object with an idField key containing a string. If provided, the returned JSON objects will include their document ID mapped to a property with the name provided by idField.
[Emphasis mine]
Upvotes: 26
Reputation: 81
I got so annoyed that there isn't a method for this, so I made one to share with everyone. Something this basic should be built into the the library itself.
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 };
})))
}
Note that this.afs is type AngularFirestore that should be in the constructor.
Upvotes: 2
Reputation: 112
You can use RXJS pipelines, easy read
AllDrivers() {
return this.collection.snapshotChanges().pipe(
map(
(action) => {
return action.map( a => {
return {...a.payload.doc.data(),
id: a.payload.doc.id
};
});
}
),
take(1)
);
Upvotes: -1
Reputation: 6900
.valueChanges()
returns only data without any meta data. you can use .snapshotChanges()
for that
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 };
});
});
also import import { Observable } from 'rxjs/Observable';
For your second question how to add id when pushing data to firestore. try
//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();
Now you can use .valueChanges()
to get the data.
Upvotes: 14