繁体   English   中英

在另一个屏幕上从该数据库中获取数据之前,我如何才能等到数据在一个屏幕中添加到数据库中? (反应原生,Firebase)

[英]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.

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