我正在尝试从firebase获取一个集合,然后调用一个将插入数据的函数。问题是在比较函数结束之前调用了插入数据......
这是我要遵循的指南:
1 - 获取游戏输入并创建一个包含推荐视频的阵列
2 - 从用户那里获取已推荐的视频
3 - 将视频与数组进行比较以排除重复项。
4 - 继续执行下一个功能,将数组插入firebase。
问题是,对于第4步,我需要完成第3步。但那并没有发生。关于如何解决这个问题的任何建议?
export const generateRecommendationsFromGame = (participantID) => {
var newRec = [];
let userRef = firebase.firestore().collection("users").doc(participantID);
//1 Game inputs
return firebase.firestore().collection("inputGame").where("user", "==", userRef).onSnapshot({}, function(querySnapshot) {
querySnapshot.forEach(function(doc) {
let consagua = doc.data().consagua;
let enfart = doc.data().enfartamento;
let mastig = doc.data().mastigacao;
let mexdorm = doc.data().mexerdormir;
let emoc = doc.data().emocoes;
//13
//V2.3.2
if (Number(consagua) >= 3) {
newRec.push('V2.3.2');
}
//15
//V3.1
if (Number(enfart) >= 25) {
newRec.push('V3.1');
}
//16
//V3.2
if (Number(mastig) >= 40) {
newRec.push('V3.2');
}
//17
//V3.3
//18
//V3.4
if (Number(mexdorm) >= 3) {
newRec.push('V3.3');
newRec.push('V3.4');
}
//19
//V3.5
if (Number(emoc) >= 2) {
newRec.push('V3.5');
}
//2 - User Videos
return firebase.firestore().collection("recommendedVideo").where("user", "==", userRef).get().then(result2 => {
result2.forEach(doc2 => {
//3 - Get video ref to compate to Array
var videoFef = doc2.data().video.id;
firebase.firestore().collection("videos").doc(videoFef).get().then(
function(doc2) {
if (doc2.exists) {
var sequence = doc2.data().sequenceNumberID;
for (var i = 0; i < newRec.length; i++) {
if (String(sequence) == String(newRec[i])) {
var index = newRec.indexOf(newRec[i]);
if (index > -1) {
newRec.splice(index, 1);
}
}
}
} else alert("Não existe doc videos");
}
)
});
}).then(() => {
insertData(newRec);
})
});
})
};
然后,在比较视频并删除重复后,我想调用一个函数在Firebase上插入视频。
export const insertData= (arr) => {
var newRec = arr.split(',');
for (var i = 0; i < newRec.length; i++) {
var ref = newRec[i];
firebase.firestore().collection("videos").where("sequenceNumberID", "==", ref.toString()).onSnapshot(function (querySnapshot) {
querySnapshot.forEach(function (doc) {
firebase.firestore().collection("recommendedVideo").add({
seen: false,
user: firebase.firestore().collection('users').doc(participantID),
video: firebase.firestore().collection('videos').doc(doc.id)
}).catch(function (error) {
alert(error);
})
});
});
}
}
答案 0 :(得分:2)
您需要为每个doc2
进行异步查询,然后在完成所有查询后继续insertData
。正确的工具是Promise.all
,一旦解决了数组中的所有promise,它将获取一系列promise并解析。因此,将每个doc2
映射到Promise。
除了Promise.all
之外,使用async
/ await
可以大大减少缩进地狱。
请注意,您在doc2
内隐藏(复制)forEach
变量,这很容易引起混淆 - 最好将其称为其他名称(例如doc3
) :
使querySnapshot.forEach
异步:
querySnapshot.forEach(async (doc) => {
然后:
//2 - User Videos
const result2 = await firebase.firestore().collection("recommendedVideo").where("user", "==", userRef).get();
await Promise.all(result2.map(async (doc2) => {
//3 - Get video ref to compate to Array
const videoFef = doc2.data().video.id;
const doc3 = await firebase.firestore().collection("videos").doc(videoFef).get();
if (!doc3.exists) {
alert("Não existe doc videos");
return;
}
var sequence = doc3.data().sequenceNumberID;
for (var i = 0; i < newRec.length; i++) {
if (String(sequence) !== String(newRec[i])) return;
var index = newRec.indexOf(newRec[i]);
if (index > -1) newRec.splice(index, 1);
}
}));
// end of Promise.all
insertData(newRec);
答案 1 :(得分:0)
以下是我设法解决这个问题的方法。
var reads = [];
await firebase.firestore().collection("recommendedVideo").where("user", "==", userRef).onSnapshot({}, function (querySnapshot) {
querySnapshot.forEach(async doc => {
reads.push(doc);
})
return Promise.all(reads.map(async (doc1) => {
//3 - Get video ref to compate to Array
const videoFef = doc1.data().video.id;
const doc3 = await firebase.firestore().collection("videos").doc(videoFef).get();
if (!doc3.exists) {
alert("Não exisste doc videos");
return;
}
var sequence = doc3.data().sequenceNumberID;
for (var i = 0; i < newRec.length; i++) {
if (String(sequence) == String(newRec[i])) {
var index = newRec.indexOf(newRec[i]);
if (index > -1) {
newRec.splice(index, 1);
}
}
}
})).then(function() {
insertData(newRec, participantID);
});
});
感谢CertainPerformance提供的帮助。