I am trying to get a collection from firebase and later call a function that will insert data. Problem is that the insert data is been called before the compare function ends...
This is the guide that I am following:
1 - Get the game inputs and create an array with the videos to recommend
2 - Get the already recommended videos from user
3 - Compare the videos with the array to exclude duplicates.
4 - Proceed to next function to insert the array to firebase.
Problem is that for step 4 I need step 3 to be completed. But that's not happening. Any suggestion on how to solve this?
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);
})
});
})
};
Then, after the video is compared and the duplicated excluded, I want to call a functions to insert the videos on 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);
})
});
});
}
}
You need to make an asynchronous query for each doc2
and then continue on to insertData
after all queries are done. The right tool for this is Promise.all
, which takes an array of promises and resolves once all promises in the array are resolved. So, map each doc2
to a Promise.
In addition to Promise.all
, use async
/ await
to greatly reduce your indentation hell.
Note that you're shadowing (duplicating) the doc2
variable inside the forEach
, which can easily cause confusion - better to call it some other name (eg doc3
):
Make the querySnapshot.forEach
async:
querySnapshot.forEach(async (doc) => {
and then:
//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);
Here is how I managed to solve this.
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);
});
});
Thanks CertainPerformance for the help.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.