From 46bc908b333426b6ed14fdf818d73efd2b2ca284 Mon Sep 17 00:00:00 2001 From: Vignesh B S <55937928+VinuB-Dev@users.noreply.github.com> Date: Thu, 5 Dec 2024 00:35:36 +0530 Subject: [PATCH] Fix: Handle firestore 'in' operator limitation by chunking queries; update field name from 'assigneeId' to 'assignee' (#2279) --- models/tasks.js | 20 +++++++++++++++---- services/tasks.js | 6 +++--- services/users.js | 2 +- .../abandoned-tasks/departed-users.js | 12 ++++------- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/models/tasks.js b/models/tasks.js index d7e22bffe..b7a2f40da 100644 --- a/models/tasks.js +++ b/models/tasks.js @@ -22,6 +22,7 @@ const { } = TASK_STATUS; const { OLD_ACTIVE, OLD_BLOCKED, OLD_PENDING, OLD_COMPLETED } = TASK_STATUS_OLD; const { INTERNAL_SERVER_ERROR } = require("../constants/errorMessages"); +const { BATCH_SIZE_IN_CLAUSE } = require("../constants/firebase"); /** * Update multiple tasks' status to DONE in one batch operation. @@ -750,11 +751,22 @@ const fetchIncompleteTasksByUserIds = async (userIds) => { return []; } try { - const incompleteTasksQuery = await tasksModel.where("assigneeId", "in", userIds).get(); + const userIdChunks = []; - const incompleteTaskForUsers = incompleteTasksQuery.docs.filter( - (task) => !COMPLETED_STATUSES.includes(task.data().status) - ); + for (let i = 0; i < userIds.length; i += BATCH_SIZE_IN_CLAUSE) { + userIdChunks.push(userIds.slice(i, i + BATCH_SIZE_IN_CLAUSE)); + } + + const promises = userIdChunks.map(async (userIdChunk) => { + const querySnapshot = await tasksModel.where("assignee", "in", userIdChunk).get(); + return querySnapshot.docs.map((doc) => doc.data()); + }); + + const snapshots = await Promise.all(promises); + + const incompleteTasks = snapshots.flat(); + + const incompleteTaskForUsers = incompleteTasks.filter((task) => !COMPLETED_STATUSES.includes(task.status)); return incompleteTaskForUsers; } catch (error) { diff --git a/services/tasks.js b/services/tasks.js index 370e381ec..bedf8a851 100644 --- a/services/tasks.js +++ b/services/tasks.js @@ -66,13 +66,13 @@ const fetchOrphanedTasks = async () => { const userIds = userSnapshot.docs.map((doc) => doc.id); - const orphanedTasksQuerySnapshot = await tasksQuery.fetchIncompleteTasksByUserIds(userIds); + const orphanedTasksData = await tasksQuery.fetchIncompleteTasksByUserIds(userIds); - if (orphanedTasksQuerySnapshot.empty) { + if (orphanedTasksData.empty) { return []; } - const orphanedTasks = orphanedTasksQuerySnapshot.map((doc) => doc.data()); + const orphanedTasks = orphanedTasksData; return orphanedTasks; } catch (error) { diff --git a/services/users.js b/services/users.js index 240f5c507..94646d896 100644 --- a/services/users.js +++ b/services/users.js @@ -15,7 +15,7 @@ const getUsersWithIncompleteTasks = async (users) => { return []; } - const userIdsWithIncompleteTasks = new Set(abandonedTasksQuerySnapshot.map((doc) => doc.data().assigneeId)); + const userIdsWithIncompleteTasks = new Set(abandonedTasksQuerySnapshot.map((doc) => doc.assignee)); const eligibleUsersWithTasks = users.filter((user) => userIdsWithIncompleteTasks.has(user.id)); diff --git a/test/fixtures/abandoned-tasks/departed-users.js b/test/fixtures/abandoned-tasks/departed-users.js index d16ca551b..ad58e877c 100644 --- a/test/fixtures/abandoned-tasks/departed-users.js +++ b/test/fixtures/abandoned-tasks/departed-users.js @@ -76,8 +76,7 @@ const tasksData = [ updatedAt: 1727027999, startedOn: 1727027777, endsOn: 1731542400, - assignee: "archived_user1", - assigneeId: "user1_id", + assignee: "user1_id", github: { issue: { html_url: "https://github.com/org/repo/issues/1", @@ -97,8 +96,7 @@ const tasksData = [ updatedAt: 1727027999, startedOn: 1727027777, endsOn: 1731542400, - assignee: "archived_user2", - assigneeId: "user2_id", + assignee: "user2_id", github: { issue: { html_url: "https://github.com/org/repo/issues/2", @@ -118,8 +116,7 @@ const tasksData = [ updatedAt: 1727027999, startedOn: 1727027777, endsOn: 1731542400, - assignee: "archived_user1", - assigneeId: "user1_id", + assignee: "user1_id", github: { issue: { html_url: "https://github.com/org/repo/issues/3", @@ -139,8 +136,7 @@ const tasksData = [ updatedAt: 1727027999, startedOn: 1727027777, endsOn: 1731542400, - assignee: "active_user", - assigneeId: "user3_id", + assignee: "user3_id", github: { issue: { html_url: "https://github.com/org/repo/issues/4",