[英]How can I wait until data is added to a database in one screen before fetching the data from that database on another screen? (React Native, Firebase)
所以我一直在努力解决以下问题:我有两个屏幕:ProgressScreen 和 StudyScreen。
在 ProgressScreen 上,我通过 setUserCard() 将数据添加到 firestore 数据库。 然后我导航到 StudyScreen,我想在其中通过 getUserCard() 获取这些数据并呈现它。
但似乎 getUserCard 试图在数据上传之前获取数据
一旦设置 function 完成后,我尝试设置 cardIsSet state,然后我通过 navigation.navigate 将其传递到第二个屏幕,但不幸的是,这不起作用。 你有什么我可以尝试的其他想法吗?
这是我的代码:
// callback() calls, getCards() that calls setUserCard(), which adds the cards to the database)
const ProgressScreen = ({ books, user, parentFunc }) => {
const navigation = useNavigation();
const [bookIndex, setBookIndex] = useState(0)
const [lastBook, setLastBook] = useState(false)
const [booksInProgress, setBooksInProgress] = useState([])
const [isLoaded, setIsLoaded] = useState(false)
const pickerRef = useRef();
// Get the card object
const getCards = async (book, page) => {
const cardRef = db.collection('cards').where("book", "==", book);
try {
const cards = await cardRef.get();
for (const doc of cards.docs) {
const data = doc.data();
if (page >= data.page) {
setUserCard(data)
}
}
} catch (err) {
alert(err)
}
}
// Creates a userCard in firestore
const setUserCard = async (data) => {
const userCardId = auth.currentUser.uid + "_" + data.cardID;
const userCardRef = db.collection("userCards").doc(userCardId);
const document = await userCardRef.get();
try {
document.data().cardID
console.log("Document exists")
} catch (error) {
console.log("Document does not exists")
console.log(data.book)
userCardRef.set({
book: data.book,
cardID: data.cardID,
question: data.question,
answer: data.answer,
userID: auth.currentUser.uid,
nextReview: firebase.firestore.FieldValue.serverTimestamp(),
step: 0,
})
}
}
/**
* Pickerref is a function in the WheelPicker component (child). It only runs when bookIndex changes.
*/
useEffect(() => {
if (user.reading.length !== 0 && isLoaded) {
pickerRef.current()
}
SetReadingBooks()
}, [bookIndex, lastBook, isLoaded])
// Find all the readingbooks
const SetReadingBooks = () => {
let booksReading = [];
for (let i = 0; i <= user.reading.length - 1; i++) {
let book = books.filter(d =>
d.title == user.reading[i].title)
booksReading.push(book[0])
}
setBooksInProgress(booksReading)
setIsLoaded(true)
}
/** Function that updates the bookIndex */
const nextBook = (() => {
if (bookIndex < user.reading.length - 1) {
setBookIndex(bookIndex + 1)
}
if (bookIndex === user.reading.length - 1) {
setLastBook(true)
}
})
// This is only called when bookIndex is updated
const callback = useCallback((selectedItem) => {
if (bookIndex !== 0 && !lastBook) {
getCards(booksInProgress[(bookIndex - 1)].title, selectedItem)
updatePage(selectedItem, (bookIndex - 1))
} if (lastBook) {
console.log("callback triggered")
getCards(booksInProgress[(bookIndex)].title, selectedItem)
updatePage(selectedItem, bookIndex)
navigation.navigate("StudyQuestions");
}
});
const updatePage = (pageProgress, index) => {
parentFunc();
const reading = user.reading
const objectToChange = reading[index];
objectToChange.page = pageProgress;
db.collection("userObjects").doc(user.uid).update({
reading: reading
}).then(function () {
console.log("Page updated");
});
}
if ((user.reading.length === 0)) {
return (
<View style={styles.container}>
<Text> Kindly select a a book</Text>
</View >
);
} if(isLoaded) {
return (
<View style={styles.container}>
<Text style={styles.imageTitle}> {booksInProgress[bookIndex].title} </Text>
<Text style={styles.imageSubtitle}> {booksInProgress[bookIndex].author} </Text>
<Text style={styles.imageSubtitle}> How far have you read? </Text>
<WheelPicker pickerRef={pickerRef}
pages={booksInProgress[bookIndex].pageNumber}
currentProgress={user.reading[bookIndex].page}
parentCallback={callback}
/>
<Button title="Next" onPress={() => nextBook()} />
<View>
</View>
</View >
)
} else {
return (
<View>
<Text> Loading </Text>
</View>
)
}
};
export default ProgressScreen
const styles = StyleSheet.create({ ... })
然后我从 StudyScreen 的数据库中获取卡片。 但如前所述,它在添加卡片之前运行它,这意味着它返回一个空数组。
const StudyScreen = () => {
// states
const [studyCards, setStudyCards] = useState([]);
const [isLoaded, setIsLoaded] = useState(false)
useEffect(() => {
getUserCards();
}, [isLoaded])
const getUserCards = async () => {
console.log("This is getUserCards")
const userCardRef = await db.collection('userCards');
const currentTime = firebase.firestore.Timestamp.fromDate(new Date())
try {
userCardRef.where("nextReview", "<=", currentTime).where("userID", "==", auth.currentUser.uid).onSnapshot(snapshot => {
setStudyCards(snapshot.docs.map(doc => doc.data()))
console.log(snapshot.docs.map(doc => doc.data()))
})
setIsLoaded(true)
} catch (err) {
alert(err)
}
}
return (
<View>
<TouchableOpacity>
</TouchableOpacity>
<ScrollView
scrollEnabled={false}
>
{
studyCards.map(({ answer, question, nextReview, step, userID, cardID }) => (
<StudyCard
answer={answer}
question={question}
cardsToStudy={studyCards.length}
step={step}
nextReview={nextReview}
userID={userID}
cardID={cardID}
getUserCards={getUserCards}
/>
))}
</ScrollView>
</View>
);
};
const styles = StyleSheet.create({ ... });
export default StudyScreen;
谢谢阅读
编辑:为两个组件添加了整个代码
请添加完整的代码,包括 Compenent ProgressScreen 和 StudyScreen。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.