繁体   English   中英

将两个以上的 collections 从 Firestore 复制到另一个集合不起作用

[英]Copying more than two collections from firestore to another collection doesn't work

所以我的 Firestore 数据库中有四个 collections:

  1. 英语问题
  2. 数学题
  3. 科学问题
  4. 宗卡问题

我正在尝试从 collections 复制所有数据,并将其放在每个用户的一个集合中。 所以它看起来像这样。

  1. 用户名(集合)
    • MathQuestions (doc) - Questions (collection)
    • EnglishQuestions (doc) - Questions (collection)
    • ScienceQuestions (doc) - Questions (collection)
    • DzongkhaQuestions (doc) - Questions (collection) 但是,当我尝试这样做时,它的行为很奇怪,有时,所有四个 collections 都被复制到用户名集合中,但其他时候只有前两个 collections 或第一个集合被复制。

在我有你一个接一个地为每个集合调用数据库的部分之前。 由于这不起作用,我尝试将每个调用都设为自己的 function,如下所示。 可悲的是,这也不起作用。 任何帮助将不胜感激。

接受@ralemos 的建议后,它仍然不起作用,但新代码如下所示。

    fire
      .auth()
      .createUserWithEmailAndPassword(this.state.email, this.state.password)
      .then((u) => {
        let user = fire.auth().currentUser;
        console.log(user);
        if (user != null) {
          user
            .updateProfile({
              displayName: this.state.name,
            })
            .then((r) => {
              let db = fire.firestore();
              let data = {
                name: this.state.name,
                email: this.state.email,
                college: this.state.college,
                dzongkhag: this.state.dzongkhag,
              };
              db.collection(this.state.email).doc("UserProfile").set(data);
              this.copyMathDatabase();
            });
        }
      });
  }
  copyMathDatabase() {
    let db = fire.firestore();
    db.collection("Questions")
      .get()
      .then((snapshot) => {
        snapshot.forEach((doc) => {
          db.collection(this.state.email).doc("MathQuestions").collection("Questions").doc(doc.id).set({
            Category: doc.data().Category,
            Choice: doc.data().Choice,
            CorrectAnswer: doc.data().CorrectAnswer,
            IsCorrectAnswer: doc.data().IsCorrectAnswer,
            IsWrongAnswer: doc.data().IsWrongAnswer,
            Question: doc.data().Question,
            UserHasNotResponded: doc.data().UserHasNotResponded,
            Marked: doc.data().Marked,
          });
          console.log("Math Questions: ", doc.id);
        });
        this.copyEnglishDatabase();
        console.log(" Done copying the Math database ");
      });
  }

  copyEnglishDatabase() {
    let db = fire.firestore();
    db.collection("EnglishQuestions")
      .get()
      .then((snapshot) => {
        snapshot.forEach((doc) => {
          db.collection(this.state.email).doc("EnglishQuestions").collection("Questions").doc(doc.id).set({
            Category: doc.data().Category,
            Choice: doc.data().Choice,
            CorrectAnswer: doc.data().CorrectAnswer,
            IsCorrectAnswer: doc.data().IsCorrectAnswer,
            IsWrongAnswer: doc.data().IsWrongAnswer,
            Question: doc.data().Question,
            UserHasNotResponded: doc.data().UserHasNotResponded,
            Marked: doc.data().Marked,
            Passage: doc.data().Passage,
            isPassageQuestion: doc.data().isPassageQuestion,
          });
          console.log("English Questions: ", doc.id);
        });
       
        console.log("Done copying the English database");
      });
  }

请记住,许多/大多数 Firestore 调用都会返回promise - 这意味着稍后会返回操作的结果,可能会晚。 一个接一个接一个电话并不意味着一个会等待另一个——这根本不是 promise 的作用。 您可能已经看到一些使用 async/await 的代码,它们看起来像是在相互等待——但它只是“语法糖”(即让它看起来不错)隐藏了“幕后”仍然存在承诺的事实。

对于您的示例,我将执行以下操作:

copyMathDatabase() {
    let db = fire.firestore();
    return db.collection("Questions")
    ...
}

copyEnglishDatabase() {
    let db = fire.firestore();
    return db.collection("EnglishQuestions")
    ...
}

请注意“返回” - 每个 function 现在返回结果的PROMISE ,这将在稍后的某个时间发生。 然后,在您的授权 function 区域:

  fire
      .auth()
      .createUserWithEmailAndPassword(this.state.email, this.state.password)
      .then((u) => {
        let user = fire.auth().currentUser;
        console.log(user);
        if (user != null) {
          user
            .updateProfile({
              displayName: this.state.name,
            })
            .then((r) => {
              let db = fire.firestore();
              let data = {
                name: this.state.name,
                email: this.state.email,
                college: this.state.college,
                dzongkhag: this.state.dzongkhag,
              };
              return db.collection(this.state.email).doc("UserProfile").set(data);
            })
            .then(() => {
              return this.copyMathDatabase();
             })
            .then(() => {
              return this.copyEnglishDatabase();
            };
        }
      });
  }

注意 - the.set() 的结果返回一个PROMISE完成后完成; .then() 等待 promise然后执行 copyMathDatabase(),完成后返回PROMISE完成; .then() 等待 promise然后执行 copyEnglishDatabase(),它在完成后返回PROMISE完成。

这个问题表明您对 Promise 的确切含义知之甚少——而这种理解对于使用 Firestore 是绝对关键和必要的。 在继续之前,您需要 go 并详细自学承诺。 您还应该了解 aync/await 语法是什么,以及它的实际作用。 这不是你学习这些东西的地方。

这很可能是由调用copyMathDatabase()copyEnglishDatabase()引起的同步问题,它们都是异步的,依次尝试将代码块更改为以下内容:

db.collection(this.state.email).doc("UserProfile").set(data).then(() =>{
    this.copyMathDatabase().then(() => {
        this.copyEnglishDatabase();
    });
});

这样您就可以强制您的代码以正确的顺序执行并减少错误,这应该可以解决您面临的问题。

暂无
暂无

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

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