Reputation: 189
I try to figure out how I can wait for several promises to be executed before the function ends.
Essentially, this is what I try to do:
Here is what I tried so far:
A) Main function (starts the first level of promises):
export function cleanUpAllData(user) {
const userId = user.uid;
const promises = [];
promises.push(deleteCategoriesData(userId)); // this works fine
promises.push(deleteUserAndGroupData(userId)); // this one has other promises which still run when Promise.all() is finished
Promise.all(promises)
.then(() => {
return "ok"; // this works so far, but not all promises are resolved
})
.catch(errPromises => {
console.log("an error occured during the processing of main promises");
console.log(errPromises, errPromises.code);
return "error";
})
}
B) deleteUserAndGroupData function (the other promise is working fine): each group found in the user data starts another level of promises and also triggers a thrid level of promises (deleteGroup) - the rest is working fine
function deleteUserAndGroupData(userId) {
const promisesUserData = [];
return admin.firestore().collection('users').doc(userId).collection('groups').get()
.then(userGroups => {
userGroups.forEach(userGroupData => {
// delete group data
promisesUserData.push(deleteGroups(userId, userGroupData.id)); // here are other promises that need to be resolved - somewhere is a problem
// delete all Groups in Users (subcollection)
promisesUserData.push(deleteGroupInUser(userId, userGroupData.id)); // this works fine
});
Promise.all(promisesUserData)
.then(() => {
admin.firestore().collection('users').doc(userId).delete()
.then(() => {
return "user data deleted"; // works fine
})
.catch(() => {
console.log("an error occured during deleting of user");
return "error";
});
})
.catch(errPromises => {
console.log("an error occured during the processing of promisesUserData");
console.log(errPromises, errPromises.code);
return "error";
})
})
.catch(errUserGroups => {
console.log(errUserGroups, errUserGroups.code);
return "no groups in User";
});
}
C) deleteGroups functions: deletes the sub collections in the group (works fine) and after that the group shall be deleted if there is no other user (which does not work)
function deleteGroups(userId,groupId) {
const promisesDeleteGroups = [];
// delete groups subcollection data
promisesDeleteGroups.push(deleteGroupRole(userId, groupId));
promisesDeleteGroups.push(deleteGroupUser(userId, groupId));
return Promise.all(promisesDeleteGroups).then(() => {
checkForOthers(groupId);
}).catch(errDeleteGroupSubcollections => {
console.log("an error occured during the processing of promisesDeleteGroups");
console.log(errDeleteGroupSubcollections, errDeleteGroupSubcollections.code);
return "error";
});
}
D) checkForOthers function - checks if there is any entry in the subcollection and shall start to delete the group (but does not)
function checkForOthers(groupId) {
return admin.firestore().collection('groups').doc(groupId).collection('users').get()
.then(groupUsers => {
return "other users exist - group should not be deleted";
})
.catch(errGroupUsers => {
// console.log("no other group members - group can be deleted");
// return "no other group members - group can be deleted";
console.log(errGroupUsers, errGroupUsers.code);
checkForInvitesAndDelete(groupId);
});;
}
E) checkForInvitesAndDelete: first I want to delete another subcollection which might or might not exists, if another user has been invited to the group; then it should trigger the final group delete (which seems not to work)
function checkForInvitesAndDelete(groupId) {
const promisesInvitesAndDelete = [];
return admin.firestore().collection('groups').doc(groupId).collection('invitations').get()
.then(groupInvitations => {
console.log("delete open Group Invitations");
groupInvitations.forEach(groupInvite => {
promisesInvitesAndDelete.push(deleteGroupInvite(groupId, groupInvite.id));
});
Promise.all(promisesInvitesAndDelete)
.then(() => {
deleteGroup(groupId)
})
.catch(errPromisesInvitesAndDelete => {
console.log("an error occured during the processing of deleting group invites");
console.log(errPromisesInvitesAndDelete, errPromisesInvitesAndDelete.code);
return "error";
});
})
.catch(() => {
console.log("no open invitations");
deleteGroup(groupId);
});
}
F) deleteGroup function
function deleteGroup(groupId) {
return admin.firestore().collection('groups').doc(groupId).delete();
}
I am relatively new to programming, especially Firebase Functions, so any help would be appreciated!!
Thank you!
Upvotes: 4
Views: 1817
Reputation: 189
I added the 'return' statements which helped a lot, but that was not the full answer.
In (D) I thought that if my collection has no data, it would run into the 'catch' phase, but it is not. So, I needed to check for an empty result set in my 'then' phase.
if (groupUsers.empty) {
return checkForInvitesAndDelete(groupId);
} else {
return "other users exist - group should not be deleted";
}
Same with the function (E) when there is no open invitation.
Upvotes: 0
Reputation: 13103
You are not using the return
keyword everywhere, where it should be. If you do a async
task, you must 'return
' it someway.
Some examples:
example A: add return
before Promise.all(promises)
... B: add return
before Promise.all(promisesUserData)
... C: add return
before checkForOthers(groupId)
... D: add return
before checkForInvitesAndDelete(groupId)
... E: add return
before Promise.all(promisesInvitesAndDelete)
and deleteGroup(groupId)
Upvotes: 5