I have this function in my TaskService:
func deleteTask(task: DistributionTask) async throws -> Void {
let (tasksCollection, userTasksIdsField, teamTasksIdsField) = task.isCompleted
? (FirestoreConstants.CollectionpletedTasks,
FirestoreConstants.Field.UserpletedTaskIds,
FirestoreConstants.Field.TeampletedTaskIds)
: (FirestoreConstants.Collection.activeTasks,
FirestoreConstants.Field.User.activeTaskIds,
FirestoreConstants.Field.Team.activeTaskIds)
try await taskRepository.deleteTask(from: tasksCollection, taskID: task.id)
try await teamRepository.removeTaskReferenceFromTeam(field: teamTasksIdsField, teamID: task.teamId, taskID: task.id)
try await userRepository.removeTaskReferenceFromUser(field: userTasksIdsField, userID: task.distributorId, taskID: task.id)
}
func deleteTask(from collection: String, taskID: String) async throws -> Void {
try await db.collection(collection).document(taskID).delete()
}
func removeTaskReferenceFromUser(field: String, userID: String, taskID: String) async throws -> Void {
}
func removeTaskReferenceFromTeam(field: String, teamID: String, taskID: String) async throws -> Void {
try await db.collection(FirestoreConstants.Collection.teams).document(teamID).updateData([
field: FieldValue.arrayRemove([taskID])
])
}
and there are three functions defined in different repositories (task, user, team) but they need to be done atomically for example with runTransaction method but the problem is if I coordinate those 3 functions from one single TaskService I can't use transaction.
In addition, I do not want to just wrap those 3 calls with runTransaction in my service because that would mix aplication logic with firebase logic.
My question is how to keep application and firebase logic separated but do those 3 delete functions as atomic operation?
I tried making some kind of transcation coordinator but it did not work.