0

I am using the Google Firestore Emulator locally for development. However, when I query the database data, I find that the results are inconsistent and not correct each time. Here is the detailed information.

1.This is my firestore setup:

/**
 * Firebase configuration for both local development and production
 */
import { initializeApp, getApps, FirebaseApp } from 'firebase/app';
import { getFirestore, connectFirestoreEmulator, Firestore } from 'firebase/firestore';
import { getAuth, connectAuthEmulator, Auth } from 'firebase/auth';
import logger from 'src/logger.ts';
// Firebase configuration
const firebaseConfig = {
 // For local development with emulator, these can be dummy values
 apiKey: process.env.FIREBASE_API_KEY || 'dummy-api-key',
 authDomain: process.env.FIREBASE_AUTH_DOMAIN || 'dummy-project.firebaseapp.com',
 projectId: process.env.FIREBASE_PROJECT_ID || 'dummy-project',
 storageBucket: process.env.FIREBASE_STORAGE_BUCKET || 'dummy-project.appspot.com',
 messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID || '123456789',
 appId: process.env.FIREBASE_APP_ID || 'dummy-app-id',
};
// Initialize Firebase app
let app: FirebaseApp;
if (getApps().length === 0) {
 app = initializeApp(firebaseConfig);
 logger.info('Firebase app initialized');
} else {
 app = getApps()[0];
 logger.info('Using existing Firebase app');
}
// Initialize Firestore
export const db: Firestore = getFirestore(app);
// Initialize Auth
export const auth: Auth = getAuth(app);
// Connect to emulators in development
if (process.env.NODE_ENV === 'development') {
 try {
 // Always connect to emulators in development
 connectFirestoreEmulator(db, 'localhost', 8080);
 logger.info('Connected to Firestore emulator on localhost:8080');
 connectAuthEmulator(auth, 'http://localhost:9099');
 logger.info('Connected to Auth emulator on localhost:9099');
 } catch (error) {
 logger.warn(`Could not connect to Firebase emulators: ${error}`);
 logger.info('Make sure to start Firebase emulators with: firebase emulators:start');
 }
}
export { app };

2.Then I start the Emulator by make firebase emulators:start --only firestore --project dummy-project

3.I do something and there are some items in my database.

item1: {...., expiredAt: {nanoseconds: 123000000, seconds: 1757341144}}
item2: {...., expiredAt: {nanoseconds: 76000000, seconds: 1757341146}}
item3: {...., expiredAt: {nanoseconds: 200000000, seconds: 1757341133}}

4.I try to get these 3 items by executing findUnexpiredThreads() function:

import {
 Firestore,
 collection,
 doc,
 setDoc,
 getDoc,
 getDocs,
 updateDoc,
 query,
 where,
 orderBy,
 limit,
 getCountFromServer,
} from 'firebase/firestore';
 async findUnexpiredThreads(): Promise<IChatThread[]> {
 try {
 const q = query(
 collection(this.db, this.threadsCollection),
 where('expiresAt', '>', toFirestoreSafe(new Date()))
 );
 const snapshot = await getDocs(q);
 return snapshot.docs.map(doc => fromFirestoreSafe(doc.data())) as IChatThread[];
 } catch (error) {
 logger.error(`Failed to find unexpired chat threads: ${error}`);
 return [];
 }
 }
// Convert app data to Firestore-safe values: BigInt -> string, Date -> Timestamp
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function toFirestoreSafe<T = unknown>(value: T): any {
 return deepMap(value as unknown as JsonValue, v => {
 if (typeof v === 'bigint') {
 return v.toString();
 }
 if (v instanceof Date) {
 return Timestamp.fromDate(v);
 }
 return v;
 });
}
// Convert Firestore data to app-friendly values: Timestamp -> Date
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function fromFirestoreSafe<T = unknown>(value: T): any {
 return deepMap(value as unknown as JsonValue, v => {
 if (v instanceof Timestamp) {
 return v.toDate();
 }
 return v;
 });
}

Result: Sometimes it returns 0 items, sometimes it returns 1/2/3 items, the result is unstable. In theory, it should always return 3 items, because the expiredAt of these 3 items is greater than now.

I'm not sure where the problem lies. I checked the contents of the database, and they haven't been modified. I was merely making queries, but I don't know why the results are incorrect, and the results of each query are also inconsistent.

Doug Stevenson
321k37 gold badges458 silver badges474 bronze badges
asked Sep 8, 2025 at 14:47
5
  • Are you saying this problem exists only with the Firebase emulator and not with the actual Firestore cloud service? Commented Sep 8, 2025 at 14:52
  • 2
    Your case isn't reproducible. Your post says: "I do something and there are some items in my database.". Without knowing exactly what you're doing, we can't know how to reproduce the problem reliably. I strongly suggest editing the question to give exact code and instructions that anyone can follow that will cause a specific unexpected result. Also, you're not showing what deepMap is. Maybe you could also simplify the code to only the minimum required that causes the problem. Commented Sep 8, 2025 at 14:53
  • thanks, i will create a minimal demo later Commented Sep 8, 2025 at 15:05
  • I have found the reason. Following your reminder, I created a minimal demo locally, and it ran normally in the demo. Then I discovered that when the problem occurred, I stored expiredAt as a Map format (item1: {...., expiredAt: {nanoseconds: 123000000, seconds: 1757341144}}). I fixed it by not converting Date and timestamp types to maps when encountering them in toFirestoreSafe() and fromFirestoreSafe(). Anyway, thank you for your time. Commented Sep 8, 2025 at 16:30
  • Since you know the answer to your question, to help future readers please consider posting it as an actual answer (and accepting it). If you don't want to do that, please close your question. In its current state it'll almost certainly never get answered (except by you). Commented Sep 24, 2025 at 12:28

1 Answer 1

0

I discovered that when the problem occurred, I stored expiredAt as a Map format (item1: {...., expiredAt: {nanoseconds: 123000000, seconds: 1757341144}}). I fixed it by not converting Date and timestamp types to maps when encountering them in toFirestoreSafe() and fromFirestoreSafe().

answered Sep 25, 2025 at 13:05
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.