Javascript 将两个以上的收藏从firestore复制到另一个收藏不会';行不通
因此,我的firestore数据库中有四个集合:Javascript 将两个以上的收藏从firestore复制到另一个收藏不会';行不通,javascript,reactjs,firebase,google-cloud-firestore,Javascript,Reactjs,Firebase,Google Cloud Firestore,因此,我的firestore数据库中有四个集合: 英语问题 数学问题 科学问题 宗可汗问题 我试图复制这些集合中的所有数据,并将其放在每个用户的一个集合中。所以看起来是这样的 用户名(集合) 数学问题(文档)-问题(集合) 英语问题(doc)-问题(集合) 科学问题(doc)-问题(集合) Dzongkha问题(文档)-问题(收集) 然而,当我尝试这样做时,它的行为很奇怪,因为有时候,所有四个集合都会被复制到username集合中,而其他时候只有前两个集合或第一个集合被复制 在我之前,你会
- 数学问题(文档)-问题(集合)
- 英语问题(doc)-问题(集合)
- 科学问题(doc)-问题(集合)
- Dzongkha问题(文档)-问题(收集) 然而,当我尝试这样做时,它的行为很奇怪,因为有时候,所有四个集合都会被复制到username集合中,而其他时候只有前两个集合或第一个集合被复制
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");
});
}
这很可能是调用
copyMathDatabase()
和copyEnglishDatabase()
(两者都是异步的)导致的同步性问题,请依次尝试将代码块更改为以下内容:
db.collection(this.state.email).doc("UserProfile").set(data).then(() =>{
this.copyMathDatabase().then(() => {
this.copyEnglishDatabase();
});
});
copyMathDatabase() {
let db = fire.firestore();
return db.collection("Questions")
...
}
copyEnglishDatabase() {
let db = fire.firestore();
return db.collection("EnglishQuestions")
...
}
通过这种方式,您可以强制以正确的顺序执行代码并减少错误,这应该可以解决您面临的问题。请记住,许多/大多数Firestore调用都会返回一个承诺-这意味着操作的结果将在以后返回,可能要晚很多。只是一个接一个地打电话并不意味着一个人会等另一个——这根本不是承诺所能做的。您可能已经看到一些使用async/await的代码,它们看起来像是在等待对方,但只是“语法糖”(即使其看起来很好)隐藏了这样一个事实,即在“幕后”仍然有承诺 以您为例,我将执行以下操作:
db.collection(this.state.email).doc("UserProfile").set(data).then(() =>{
this.copyMathDatabase().then(() => {
this.copyEnglishDatabase();
});
});
copyMathDatabase() {
let db = fire.firestore();
return db.collection("Questions")
...
}
copyEnglishDatabase() {
let db = fire.firestore();
return db.collection("EnglishQuestions")
...
}
请注意“return”-每个函数现在都返回一个结果的承诺,这将在稍后发生。然后,在身份验证功能区域中:
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();
};
}
});
}
注意,.set()的结果返回一个承诺,该承诺将在完成时完成。然后()等待该承诺,然后执行copyMathDatabase(),它将在完成时返回一个要完成的承诺。然后()等待该承诺,然后执行copyEnglishDatabase(),该数据库在完成时返回一个要完成的承诺
这个问题表明您对承诺的确切含义知之甚少,而这种理解对于使用Firestore是绝对关键和必要的。在你继续之前,你需要去教自己详细的承诺。您还应该了解什么是aync/await语法,以及它的实际功能。这里不是您学习这些东西的地方。您的代码表明,此时您只想复制前两个集合:
js This.copyMathDatabase();这个.copyEnglishDatabase()代码>@JayCodist我删除了另外两个调用,因为我只想尝试两个。如果我只调用一个集合,它就可以工作,但只要我尝试复制两个集合,它就会表现得很奇怪。它有时复制,有时不复制。由于这两个复制例程都是异步的,您是否在顶层存在之前检查它们的完成情况(尤其是写入情况)?是的,我更改了代码,现在它强制一个在另一个可以启动之前完成,但仍然无法工作@我们可以看看你是怎么修改密码的吗?对我们来说,仅仅凭猜测提供帮助是相当困难的……我试过了,但仍然不起作用。知道为什么吗?非常感谢你的帮助。您给出的方法也部分有效。每样东西都很好用,有时所有的收藏品都被完美地复制了。但有时,只有math集合被复制,而其他集合没有被复制。有什么想法吗?什么都没有。你没有给我们任何东西看。我们应该猜猜吗?