我只需要一些帮助来获取Firestore数据库上的文档字段。链接上的示例图片image sample here是我的用户子收藏集。我试图获取所有文档字段“ groupName”,并将其全部显示在屏幕上。使用我正在使用的代码,屏幕上只会出现一个字段。
class CreateNewGroup extends Component {
constructor(props) {
super(props);
this.state = ({
groupName: '',
loading: false,
});
};
getCoordinates(query) {
console.log('start loading animation');
};
MountFSUserGroup = () => {
const curUser = firebase.auth().currentUser;
const dbUser =
firebase
.firestore()
.collection('users')
.doc(curUser.uid)
.collection('SampleGroup')
.get()
.then(snapshot => {
if (snapshot.empty) {
console.log('No matching documents.');
return;
}
snapshot.forEach(doc => {
console.log(doc.id, '=>', doc.data());
const { groupName } = doc.data();
this.setState({ groupName, loading: false });
});
})
.catch(err => {
console.log('Error getting documents', err);
});
const { groupName } = dbUser;
this.setState({ groupName, loading: true });
};
componentDidMount() {
this.MountFSUserGroup()
};
UNSAFE_componentWillMount() {
this.MountFSUserGroup()
console.log("user group mounted");
};
render() {
return (
<View style={{flex: 1,}}>
<CustomHeaderBack />
<Loader loading={this.state.loading} />
<ScrollView>
<View style={styles.body}>
<View style={styles.titleCont}>
<Text
style={styles.text1}>
SAMPLE GROUP LIST
</Text>
</View>
<View style={styles.insideCont}>
<Text
style={styles.text2}>
Select Your Group:
</Text>
<Text
style={styles.text2}>
{this.state.groupName}
</Text>
</View>
</View>
</ScrollView>
<CustomFooter />
</View>
)
}
};
export default CreateNewGroup ;
Sample screen仅显示第三个字段“ groupName:” Group Three“”,但在控制台(console log sample)上所有字段都同时列出。
如果我使用
.where('groupName', "==", true)
它转到空的错误消息“没有匹配的文档”,并且屏幕冻结。希望有人能帮上忙。预先感谢。
答案 0 :(得分:0)
目前的代码有几个问题。
this.setState({ groupName, loading: false });
-这只是将最后遇到的groupName设置为组件状态。这是原始问题。您将必须snapshot.map()
如果它不断地进行重新渲染,则该fn可能在渲染周期中的某个地方被调用。作为一般原则,最好尽可能区分数据检索和状态管理。因此,如果将getGroupNames移至其自身的函数中,并提供用户ID和Firebase实例,则可以将值设置为仅在与先前值不同时才声明。
或者,如果您使用的是挂钩,我强烈建议您这样做,然后根据用户ID使用 useMemo
或使用useEffect
进行呼叫。两种方法都只能将呼叫限制为仅在需要时。
会发生什么事情?
//...imports...
class CreateNewGroup extends Component {
constructor(props) {
super(props);
this.state = ({
groupNames: [],
loading: false,
});
};
//i might even take this out of the component and declare it as a pure js function
// as it is not using anything from 'this' and loading can be set where it is being called from too
getFSUserGroup = async () => {
try {
this.setState({ loading: false })
const curUser = firebase.auth().currentUser;
// get some value
const data = async firebase
.firestore()
.collection('users')
.doc(curUser.uid)
.collection('SampleGroup')
.get()
.map(doc => doc.data().groupName); // get all the group names for each item
this.setState({ loading: false }) // set loading as false, will trigger a render
return data // return that data from above
} catch (e) {
// failed to get documents
this.setState({ loading: false })
}// if it errored or something, it would return undefined
}
componentDidMount() {
this.getFSUserGroup().then(x => {
if (x && !this.state.groupNames) {
this.setState({ groupNames })
}
// it might not be a great idea to simply `!this.state.groupNames` though.. :(
})
};
// render and other stuff
此外,如果您是刚开始..最好看一下React Stateless Function Components,因为这样您就可以使用Hooks 其中,它巧妙地抽象了很多样板代码,这些代码涉及完成简单任务(例如您正在执行的任务)。 要详细了解为什么和方式,请查看this one