Skip to content

Optimize updateAllUserStatus Query & Filter Scheduled Statuses on Database Level#2598

Open
Soumava-221B wants to merge 1 commit into
RealDevSquad:developfrom
Soumava-221B:develop
Open

Optimize updateAllUserStatus Query & Filter Scheduled Statuses on Database Level#2598
Soumava-221B wants to merge 1 commit into
RealDevSquad:developfrom
Soumava-221B:develop

Conversation

@Soumava-221B

Copy link
Copy Markdown

Date: 16/06/2026

Developer Name: Soumava Das


Issue Ticket Number

#2597

Description

This PR optimizes the database query inside the updateAllUserStatus cron job model.

Previously, the query loaded all documents matching the futureStatus.state criteria from Firestore and performed the date filtering in application memory. This caused full collection scans/large subset scans, leading to high Firestore read costs and memory consumption.

With this change, date filtering is delegated directly to Firestore using a range query, fetching only the documents that actually need to be updated.

Key Changes

  1. Query Optimization:
    • Added .where("futureStatus.from", "<=", today) filter directly to the Firestore query to fetch only the statuses that are due/past.
  2. Proper Property Usage:
    • Replaced the private/internal _size property of the Firestore QuerySnapshot object with the standard public size property.
  3. Refactored Code Flow:
    • Moved today timestamp instantiation to the top of updateAllUserStatus to be used for both the database query and the document update timestamps.

Firestore Index Requirement

Important

Because this change introduces a multi-field compound query (equality/in filter combined with an inequality/range filter), it requires a custom composite index.

Index Details:

  • Collection ID: usersStatus
  • Fields:
    • futureStatus.state (Ascending)
    • futureStatus.from (Ascending)
    • __name__ (Ascending)

Development Tested?

  • Yes
  • No

Screenshots

Screenshot 1

Test Coverage

Screenshot 1 Screenshot 2026-06-16 at 8 41 52 PM

Additional Notes

Optimizes the database query in updateAllUserStatus by performing range filtering on the database level instead of in-memory application logic.

Key Changes:
- Added filter on futureStatus.from directly to the query.
- Replaced the internal snapshot property _size with public size property.
- Instantiated today once at the top of the updateAllUserStatus model.
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced the accuracy of user status updates to properly reflect the current date and time, ensuring correct status transitions.
    • Improved user count reporting reliability and consistency across the platform.

Walkthrough

updateAllUserStatus in models/userStatus.js gains a Firestore where clause restricting results to documents whose futureStatus.from is <= Date.now(). today is now computed with Date.now(), and summary.usersCount is read from userStatusDocs.size instead of _size.

Changes

Firestore Query Optimization in updateAllUserStatus

Layer / File(s) Summary
Query filter and usersCount fix
models/userStatus.js
Adds futureStatus.from <= today filter (with today = Date.now()) to the Firestore query and replaces userStatusDocs._size with userStatusDocs.size for summary.usersCount.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5 minutes

Possibly related issues

Poem

🐇 A query once scanned every doc in the store,
Now timestamp and state keep it lean to the core.
Date.now() decides who deserves to be found,
And _size was swapped for the .size that's sound.
Fewer reads, cleaner hops — what a burrow to bound! 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: optimizing the updateAllUserStatus query and filtering scheduled statuses at the database level rather than in application memory.
Description check ✅ Passed The description is well-detailed and directly related to the changeset, explaining the optimization, key changes, firestore index requirements, and testing confirmation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@models/userStatus.js`:
- Around line 301-304: The query in userStatusModel combining an `in` filter on
`futureStatus.state` with a range filter on `futureStatus.from` requires a
composite Firestore index that is not currently defined in the repository.
Create a composite index for the `futureStatus.state` field (in ascending order)
and `futureStatus.from` field (in ascending order) either through the Firebase
Console or by adding it to the firestore.indexes.json configuration file and
deploying it. This index must be deployed to the production Firestore instance
before merging to avoid FAILED_PRECONDITION errors at runtime when the cron
executes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 862df3df-1b4e-4a15-8e7f-af534058bd47

📥 Commits

Reviewing files that changed from the base of the PR and between 0552516 and 6a88a00.

📒 Files selected for processing (1)
  • models/userStatus.js

Comment thread models/userStatus.js
Comment on lines +301 to +304
const userStatusDocs = await userStatusModel
.where("futureStatus.state", "in", ["ACTIVE", "IDLE", "OOO"])
.where("futureStatus.from", "<=", today)
.get();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify index definitions exist for usersStatus + futureStatus.state + futureStatus.from.
# Read-only reconnaissance only.

set -euo pipefail

echo "== Candidate Firebase/Firestore config files =="
fd -i 'firebase\.json|firestore.*index.*\.json|index.*\.json'

echo
echo "== Search for usersStatus index definitions =="
rg -n -C3 '"usersStatus"|futureStatus\.state|futureStatus\.from|__name__'

echo
echo "Expected: one composite index entry for collectionGroup/collection 'usersStatus'"
echo "including fields:"
echo "  - futureStatus.state (ASCENDING)"
echo "  - futureStatus.from (ASCENDING)"
echo "  - __name__ (ASCENDING)"

Repository: RealDevSquad/website-backend

Length of output: 42423


🏁 Script executed:

cat firebase.json

Repository: RealDevSquad/website-backend

Length of output: 252


🏁 Script executed:

fd -i 'firestore' -type f | head -20

Repository: RealDevSquad/website-backend

Length of output: 243


🏁 Script executed:

fd -i 'firestore' | head -20

Repository: RealDevSquad/website-backend

Length of output: 91


🏁 Script executed:

fd 'index' -type f | grep -i firestore

Repository: RealDevSquad/website-backend

Length of output: 243


🏁 Script executed:

find . -name '*index*' -o -name '*firestore*config*' | grep -v node_modules

Repository: RealDevSquad/website-backend

Length of output: 187


🏁 Script executed:

rg -l 'composite.*index|index.*field' --type json

Repository: RealDevSquad/website-backend

Length of output: 54


🏁 Script executed:

ls -la | grep -i fire
cat firebase.json
find . -maxdepth 2 -name '*.json' | xargs grep -l 'usersStatus' 2>/dev/null | head -5

Repository: RealDevSquad/website-backend

Length of output: 318


🏁 Script executed:

find . -maxdepth 3 -name '*.json' -exec grep -l 'futureStatus\|composite' {} \; 2>/dev/null
ls -la .firebaserc .fire* 2>/dev/null || echo "No .firebaserc found"

Repository: RealDevSquad/website-backend

Length of output: 109


🏁 Script executed:

find . -name 'firestore.indexes.json' -o -name '*indexes.json'
git ls-files | grep -i 'index.*json\|firestore.*json'

Repository: RealDevSquad/website-backend

Length of output: 54


🏁 Script executed:

cat models/userStatus.js | sed -n '299,310p'
ls -la | head -20
find . -maxdepth 2 -type d | head -20

Repository: RealDevSquad/website-backend

Length of output: 1942


🏁 Script executed:

ls -la .github/workflows/
find . -maxdepth 2 -name 'README*' -o -name 'DEPLOY*' -o -name 'SETUP*'

Repository: RealDevSquad/website-backend

Length of output: 313


🏁 Script executed:

cat README.md | head -100
rg -i 'composite.*index|firestore.*index' --no-heading

Repository: RealDevSquad/website-backend

Length of output: 3640


🏁 Script executed:

cat CONTRIBUTING.md | grep -A 20 -B 5 -i 'index\|firestore'

Repository: RealDevSquad/website-backend

Length of output: 3944


Ensure the composite Firestore index for this query is created and deployed before merging to production.

The query on lines 301-304 combines an in filter on futureStatus.state with a range filter on futureStatus.from, which requires a composite index in Firestore. This index is not defined in the repository. Create it via the Firebase Console or deploy it using firestore.indexes.json to prevent runtime failures (FAILED_PRECONDITION errors) when the cron executes against production Firestore.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@models/userStatus.js` around lines 301 - 304, The query in userStatusModel
combining an `in` filter on `futureStatus.state` with a range filter on
`futureStatus.from` requires a composite Firestore index that is not currently
defined in the repository. Create a composite index for the `futureStatus.state`
field (in ascending order) and `futureStatus.from` field (in ascending order)
either through the Firebase Console or by adding it to the
firestore.indexes.json configuration file and deploying it. This index must be
deployed to the production Firestore instance before merging to avoid
FAILED_PRECONDITION errors at runtime when the cron executes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant