firebase / firebase/firebase-js-sdk

Cache does not seem to be effective in tests

Open
#8,025 4 comments 0 reactions 0 assignees View on GitHub
api: firestore needs-attention question testing-sdk
Dominant language
TypeScript
Stars
5.1k
Forks
1k
Avg merge
2d 21h
Merged PRs (30d)
37

Description

### Operating System

Windows 11

### Browser Version

N/A

### Firebase SDK Version

10.7.2

### Firebase SDK Product:

Firestore

### Describe your project's tooling

Vitest 1.2.2, Firebase Emulator

### Describe the problem

Hi!
The `getDoc` method always try to retrieve up-to-date data from the server, and read the cache only if offline. I need a method that tries first to retrieve the data from cache. So I created a method named `getDocPreferablyFromCache` to try the cache and fallback to server if the cache does not contain the data.
When trying to test this method, I run into a strange problem when running the test with Vitest: cache seems to never be popuplated... However, it seems to work fine in the browser.

The doc is not clear about when the cache is filled with data, but I expect it happens when I issue a `getDoc` or `getDocFromServer`.
But it does not seem to work that way.

Am I missing something or is there a bug?

### Steps and code to reproduce issue

`firestore.rules`
```
rules_version = '2';

service cloud.firestore {
match /databases/{database}/documents {
match /tests/{document} {
allow read, write: if true;
}
}
}
```

A test reproducing the issue:
```typescript
test('getDoc from various sources', async () => {
const app = initializeApp({
apiKey: PUBLIC_FIREBASE_API_KEY,
authDomain: PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: PUBLIC_FIREBASE_APP_ID
})
const db = initializeFirestore(app, { localCache: memoryLocalCache() })
connectFirestoreEmulator(db, '127.0.0.1', 8080)

const docPath = 'tests/doc'

await setDoc(doc(db, docPath), {
anything: 'is great'
})

const fromAnywhere = await getDoc(doc(db, docPath))
console.log('fromAnywhere was from cache?', fromAnywhere.metadata.fromCache)
expect(fromAnywhere.metadata.fromCache).toBe(false)

const fromServer = await getDocFromServer(doc(db, docPath))
console.log('fromServer was from cache?', fromServer.metadata.fromCache)
expect(fromServer.metadata.fromCache).toBe(false)

const fromCache = await getDocFromCache(doc(db, docPath))
console.log('fromCache was from cache?', fromCache.metadata.fromCache)
expect(fromCache.metadata.fromCache).toBe(true)
})
```

The output in the console:
```shell
fromAnywhere was from cache? false
fromServer was from cache? false

FirebaseError: Failed to get document from cache. (However, this document may exist on the server. Run again without setting 'source' in the GetOptions to attempt to retrieve the document from the server.)
```

I thought that maybe the cached was being filled only when the data was accessed often (as some sentence suggested that in the doc) so I put a loop aroud the `getDoc`, but even with 1000 operations, it does not change anything.
I also went into the source code to try to understand how the SDK works, but I did not manage to see where the cache was written (I only found cache reads).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.