Javascript 如何从Cloud Firestore以对象的形式获取查询结果?
在我的一个ReactJS项目中,我从firebase实时数据库迁移到了Cloud firestore。我对Firestore还是个新手 这是我需要的。考虑到我有一个集合中存储的项目的详细信息<强>“项目”<强> >p> 在实时数据库中,我只需执行以下操作即可获取数据并将其存储在以下状态:Javascript 如何从Cloud Firestore以对象的形式获取查询结果?,javascript,reactjs,firebase,google-cloud-firestore,Javascript,Reactjs,Firebase,Google Cloud Firestore,在我的一个ReactJS项目中,我从firebase实时数据库迁移到了Cloud firestore。我对Firestore还是个新手 这是我需要的。考虑到我有一个集合中存储的项目的详细信息“项目” >p> 在实时数据库中,我只需执行以下操作即可获取数据并将其存储在以下状态: database.ref('Items').once('value', (snapshot) => { this.setState({items: snapshot.val()}) }) snaps
database.ref('Items').once('value', (snapshot) => {
this.setState({items: snapshot.val()})
})
snapshot.val()
将项中的所有对象作为包含它们的单个对象返回。这使得我可以轻松地在带有Object.keys(this.state.items).map()的表中呈现它们
据我目前所知:
Firestore的情况并非如此。Firestore返回一个对象,该对象只能通过遍历每个子对象来检索子对象中的数据
所以我能想到的最好的办法是:
db.collection('Items').get().then(gotData)
gotData = (snapshot) => {
snapshot.forEach((item) => {
const item = {[item.id]: item.data()}
this.setState(previousState => ({
items : {...previousState.items, ...item}
}))
})
}
上述解决方案的问题是,状态更新的次数将等于集合中的项数。所以我想知道是否有更好的方法来实现它。差不多了,你只想把空对象放在迭代之外,就像这样
db.collection('Items').get().then(snap => {
const items = {}
snap.forEach(item => {
items[item.id] = item.data()
})
this.setState({items})
}
或者你可以把它画出来,我觉得这更容易思考
db
.collection('Items')
.get()
.then(collection => {
const items = collection.docs.map(item => {[item.id]: item.data()})
this.setState({ items })
})
或者可以使用reduce返回包含所有项目的对象
db
.collection('Items')
.get()
.then((collection) => {
const items = collection.docs.reduce((res, item) => ({...res, [item.id]: item.data()}), {});
this.setState({items})
})
差不多了,你只想把空对象放在迭代之外,就像这样
db.collection('Items').get().then(snap => {
const items = {}
snap.forEach(item => {
items[item.id] = item.data()
})
this.setState({items})
}
或者你可以把它画出来,我觉得这更容易思考
db
.collection('Items')
.get()
.then(collection => {
const items = collection.docs.map(item => {[item.id]: item.data()})
this.setState({ items })
})
或者可以使用reduce返回包含所有项目的对象
db
.collection('Items')
.get()
.then((collection) => {
const items = collection.docs.reduce((res, item) => ({...res, [item.id]: item.data()}), {});
this.setState({items})
})
我不明白你想在这里完成什么。当然,如果您迭代集合中的所有文档,您将为每个文档执行一次操作。我想知道,是否有一种方法可以只对集合中的所有对象设置一次状态,就像在实时数据库中一样。就像所有的对象都在snapshot.val()
中一样,在实时数据库中设置什么状态?我真的看不出你想要实现什么。这是我的梦想。我想获取数据并将其存储到状态中,以便在表中呈现它。您到底想获取什么?您的数据存储数据是什么样子的?看起来您正在获取整个集合,这意味着您正在迭代该集合中的每个文档。我不明白您在这里想要实现什么。当然,如果您迭代集合中的所有文档,您将为每个文档执行一次操作。我想知道,是否有一种方法可以只对集合中的所有对象设置一次状态,就像在实时数据库中一样。就像所有的对象都在snapshot.val()
中一样,在实时数据库中设置什么状态?我真的看不出你想要实现什么。这是我的梦想。我想获取数据并将其存储到状态中,以便在表中呈现它。您到底想获取什么?您的数据存储数据是什么样子的?看起来您正在获取整个集合,这意味着您正在迭代该集合中的每个文档。感谢您指导我找到正确的方法。第一种方法奏效了。第二种方法看起来更干净。但问题是,它返回一个对象数组,其中键作为访问数据的索引。所以我搜索了一下,找到了一种返回对象的方法,就像使用reduce方法返回realtime db的snap.val()一样<代码>itemsRef.get()。然后((snap)=>{const items=snap.docs.reduce((res,item)=>({…res,[item.id]:item.data()),{})this.setState({items})}
没有意识到您想要一个对象。感谢您更新回复。很高兴我能帮忙。谢谢你给我指路。第一种方法奏效了。第二种方法看起来更干净。但问题是,它返回一个对象数组,其中键作为访问数据的索引。所以我搜索了一下,找到了一种返回对象的方法,就像使用reduce方法返回realtime db的snap.val()一样<代码>itemsRef.get()。然后((snap)=>{const items=snap.docs.reduce((res,item)=>({…res,[item.id]:item.data()),{})this.setState({items})}没有意识到您想要一个对象。感谢您更新回复。很高兴我能帮忙。