繁体   English   中英

如何检索 ID 数组,然后使用它从 React Native 中的 Firestore 检索文档?

[英]How to retrieve an ID array and then use that to retrieve documents from Firestore in React Native?

我对FirebaseReact Native都很陌生 Firestore 中,我设置了一个“用户”集合,其中每个用户文档都有一个 ID 数组,表示他选择的事件。 图像

这些 ID 对应于“事件”集合中事件文档的名称。 图像

React Native 中,我试图在使用此 ID 数组检索实际事件并将它们呈现在 FlatList 之前从用户检索 selectedEvents 数组。 FlatList 使用称为“事件”的状态作为数据。 这是我的代码:

 function SelectedScreen(props) { // The events array to be displayed in the FlatList const [events, setEvents] = useState([]); const { user } = useContext(AuthContext); const userRef = firebase.firestore().collection("users").doc(user.id); const eventsRef = firebase.firestore().collection("events"); function onRefresh() { // An empty array to push events into const newSelected = []; userRef .get() .then((userDoc) => { // The retrieved ID array const selectedIds = userDoc.data().selectedEvents; // For each ID in the array, get the corresponding // event document from the "events" collection // and push it into the newSelected array selectedIds.forEach((eventId) => { eventsRef .doc(eventId) .get() .then((eventDoc) => { const event = eventDoc.data(); newSelected.push(event); }) .catch((error) => alert(error)); }); }) .catch((error) => alert(error)); // Set the events to be the newSelected array setEvents(newSelected); } return ( // A simple button to retrieve the events when pressed <Button title="Refresh" onPress={onRefresh} /> // A button to log the events to the console for testing <Button title="Test" onPress={() => console.log(events)} /> // The FlatList to show the events <FlatList data={events} keyExtractor={(event) => event.id.toString()} ItemSeparatorComponent={ListItemSeparator} renderItem={({ item }) => ( // A custom component to display each event <SelectedItem title={item.title} dateTime={item.dateTime} id={item.id} /> )} /> ); }

当我按下“刷新”按钮时,屏幕上没有任何显示(FlatList 没有显示任何内容)。 但是,当我在此之后按下“测试”按钮将“事件”记录到控制台时,它会按预期显示检索到的事件数组。

问题可能出在“事件”状态,但我不知道如何解决。 任何对后端和前端更改的建议也将不胜感激。 谢谢你。

问题是您没有适当地渲染列表,因为您缺少渲染元素的功能,这将是这样的:

const renderItem = ({item}) => {
  return <View><Text>{item.name}</Text></View>
}

请查看这篇文章以获取详细信息。

我设法通过使用map而不是forEach将每个事件 ID 与该事件匹配来解决这个问题,并使函数异步并等待每个命令。 这是我的新代码:

 function onRefresh() { const newSelected = []; userRef .get() .then(async (userDoc) => { const selectedIds = await userDoc.data().selectedEvents; if (selectedIds !== []) { await Promise.all( selectedIds.map(async (eventId) => { await eventsRef .doc(eventId) .get() .then(async (eventDoc) => { const event = await eventDoc.data(); newSelected.push(event); }) .catch((error) => alert(error)); }) ); setEvents(newSelected); } }) .catch((error) => alert(error)); }

这些事件现在按预期显示,我对之前到底出了什么问题感到困惑。 哦,好吧,只要它有效,我想。

你可以使用Promise.all()同时运行所有的 Promises

function onRefresh() {
    // An empty array to push events into
    const newSelected = [];
    return userRef
        .get()
        .then(async (userDoc) => {
            // The retrieved ID array
            const selectedIds = userDoc.data().selectedEvents;
            // For each ID in the array, get the corresponding
            // event document from the "events" collection
            // and push it into the newSelected array
            const eventsSnapshot = await Promise.all(selectedIds.map((eventId) => eventsRef.doc(eventId).get()))
            const events = eventsSnapshot.map(evt => evt.data())
            newSelected = [...newSelected, ...events];
        }).catch((error) => alert(error));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM