Skip to content

Commit 7227ffb

Browse files
Merge master into release
2 parents b2f6084 + 25cda8a commit 7227ffb

27 files changed

+1912
-110
lines changed

.changeset/cool-games-care.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@firebase/firestore': patch
3+
'firebase': patch
4+
---
5+
6+
Implemented internal logic to auto-create client-side indexes

.changeset/healthy-peas-heal.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@firebase/firestore': patch
3+
'firebase': patch
4+
---
5+
6+
Implemented internal logic to delete all client-side indexes

.github/workflows/test-all.yml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ jobs:
1717
# Install Chrome so the correct version of webdriver can be installed by chromedriver when
1818
# setting up the repo. This must be done to build and execute Auth properly.
1919
- name: install Chrome stable
20-
# Install Chrome version 110.0.5481.177-1 as some Auth tests start to fail on version 111.
21-
# Temporary: Auth team will explore what's going wrong with the auth tests.
20+
# Pin Chrome version 114.0.5735.90-1 to avoid install failures like "No such object: chromedriver/LATEST_RELEASE_115.0.5790".
21+
# The failure happens because https://chromedriver.chromium.org/downloads only goes up to version 114.
22+
# TODO(b/297380444) Update script to install the latest Chrome and ChromeDriver.
2223
run: |
2324
sudo apt-get update
2425
sudo apt-get install wget
25-
sudo wget http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_110.0.5481.177-1_amd64.deb
26-
sudo apt-get install -f ./google-chrome-stable_110.0.5481.177-1_amd64.deb --allow-downgrades
26+
sudo wget http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_114.0.5735.90-1_amd64.deb
27+
sudo apt-get install -f ./google-chrome-stable_114.0.5735.90-1_amd64.deb --allow-downgrades
2728
- uses: actions/checkout@v3
2829
- name: Set up Node (16)
2930
uses: actions/setup-node@v3
@@ -102,13 +103,14 @@ jobs:
102103
steps:
103104
# install Chrome so the correct version of webdriver can be installed by chromedriver when setting up the repo
104105
- name: install Chrome stable
105-
# Install Chrome version 110.0.5481.177-1 as some Auth tests start to fail on version 111.
106-
# Temporary: Auth team will explore what's going wrong with the auth tests.
106+
# Pin Chrome version 114.0.5735.90-1 to avoid install failures like "No such object: chromedriver/LATEST_RELEASE_115.0.5790".
107+
# The failure happens because https://chromedriver.chromium.org/downloads only goes up to version 114.
108+
# TODO(b/297380444) Update script to install the latest Chrome and ChromeDriver.
107109
run: |
108110
sudo apt-get update
109111
sudo apt-get install wget
110-
sudo wget http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_110.0.5481.177-1_amd64.deb
111-
sudo apt-get install -f ./google-chrome-stable_110.0.5481.177-1_amd64.deb --allow-downgrades
112+
sudo wget http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_114.0.5735.90-1_amd64.deb
113+
sudo apt-get install -f ./google-chrome-stable_114.0.5735.90-1_amd64.deb --allow-downgrades
112114
- name: Download build archive
113115
uses: actions/download-artifact@v3
114116
with:

.github/workflows/test-changed-auth.yml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ jobs:
1414
steps:
1515
# install Chrome first, so the correct version of webdriver can be installed by chromedriver when setting up the repo
1616
- name: install Chrome stable
17-
# Install Chrome version 110.0.5481.177-1 as test starts to fail on version 111.
18-
# Temporary: Auth team will explore what's going wrong with the auth tests.
17+
# Pin Chrome version 114.0.5735.90-1 to avoid install failures like "No such object: chromedriver/LATEST_RELEASE_115.0.5790".
18+
# The failure happens because https://chromedriver.chromium.org/downloads only goes up to version 114.
19+
# TODO(b/297380444) Update script to install the latest Chrome and ChromeDriver.
1920
run: |
2021
sudo apt-get update
2122
sudo apt-get install wget
22-
sudo wget http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_110.0.5481.177-1_amd64.deb
23-
sudo apt-get install -f ./google-chrome-stable_110.0.5481.177-1_amd64.deb --allow-downgrades
23+
sudo wget http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_114.0.5735.90-1_amd64.deb
24+
sudo apt-get install -f ./google-chrome-stable_114.0.5735.90-1_amd64.deb --allow-downgrades
2425
- name: Checkout Repo
2526
uses: actions/checkout@master
2627
with:
@@ -48,16 +49,17 @@ jobs:
4849

4950
runs-on: ubuntu-20.04
5051

51-
# Chrome webdriver version is pinned to avoid install failures like "No such object: chromedriver/LATEST_RELEASE_115.0.5790"
52-
# These are installed even in the Firefox test due to `yarn` command which pulls the devDependency listed in package.json.
52+
# Pin Chrome version 114.0.5735.90-1 to avoid install failures like "No such object: chromedriver/LATEST_RELEASE_115.0.5790".
53+
# The failure happens because https://chromedriver.chromium.org/downloads only goes up to version 114.
54+
# TODO(b/297380444) Update script to install the latest Chrome and ChromeDriver.
5355
steps:
5456
- name: install Firefox stable
5557
run: |
5658
sudo apt-get update
5759
sudo apt-get install firefox
5860
sudo apt-get install wget
59-
sudo wget http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_110.0.5481.177-1_amd64.deb
60-
sudo apt-get install -f ./google-chrome-stable_110.0.5481.177-1_amd64.deb --allow-downgrades
61+
sudo wget http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_114.0.5735.90-1_amd64.deb
62+
sudo apt-get install -f ./google-chrome-stable_114.0.5735.90-1_amd64.deb --allow-downgrades
6163
6264
- name: Checkout Repo
6365
uses: actions/checkout@master

packages/auth/test/integration/webdriver/redirect.test.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,13 @@ import { START_FUNCTION } from './util/auth_driver';
3939
use(chaiAsPromised);
4040

4141
browserDescribe('WebDriver redirect IdP test', driver => {
42-
beforeEach(async () => {
43-
await driver.pause(200); // Race condition on auth init
42+
afterEach(async function () {
43+
this.timeout(25000); // Starting browsers can be slow.
44+
45+
// Redirect tests are flaky on Chrome v111+
46+
// Stop and re-initialize the webdrive instance to prevent flakiness.
47+
await driver.stop();
48+
await driver.start('chrome');
4449
});
4550

4651
it('allows users to sign in', async () => {
@@ -327,7 +332,11 @@ browserDescribe('WebDriver redirect IdP test', driver => {
327332
expect(user.email).to.eq(user1.email);
328333
});
329334

330-
it('reauthenticate throws for wrong user', async () => {
335+
it('reauthenticate throws for wrong user', async function () {
336+
// Test is ignored for now as it fails on Chrome version 111+.
337+
// TODO(b/297245662): Investigate and unskip the test.
338+
this.skip();
339+
331340
// Sign in using pre-poulated user
332341
await driver.callNoWait(RedirectFunction.IDP_REDIRECT);
333342

@@ -350,7 +359,11 @@ browserDescribe('WebDriver redirect IdP test', driver => {
350359
);
351360
});
352361

353-
it('handles aborted sign ins', async () => {
362+
it('handles aborted sign ins', async function () {
363+
// Test is ignored for now as it fails on Chrome version 111+.
364+
// TODO(b/297245662): Investigate and unskip the test.
365+
this.skip();
366+
354367
await driver.callNoWait(RedirectFunction.IDP_REDIRECT);
355368
const widget = new IdPPage(driver.webDriver);
356369

packages/firestore/src/api.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,14 @@ export {
202202
setIndexConfiguration
203203
} from './api/index_configuration';
204204

205+
export {
206+
PersistentCacheIndexManager,
207+
getPersistentCacheIndexManager,
208+
deleteAllPersistentCacheIndexes,
209+
enablePersistentCacheIndexAutoCreation,
210+
disablePersistentCacheIndexAutoCreation
211+
} from './api/persistent_cache_index_manager';
212+
205213
/**
206214
* Internal exports
207215
*/
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/**
2+
* @license
3+
* Copyright 2023 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import {
19+
firestoreClientDeleteAllFieldIndexes,
20+
firestoreClientSetPersistentCacheIndexAutoCreationEnabled,
21+
FirestoreClient
22+
} from '../core/firestore_client';
23+
import { cast } from '../util/input_validation';
24+
import { logDebug, logWarn } from '../util/log';
25+
26+
import { ensureFirestoreConfigured, Firestore } from './database';
27+
28+
/**
29+
* A `PersistentCacheIndexManager` which you can config persistent cache indexes
30+
* used for local query execution.
31+
*
32+
* To use, call `getPersistentCacheIndexManager()` to get an instance.
33+
*
34+
* TODO(CSI) Remove @internal to make the API publicly available.
35+
* @internal
36+
*/
37+
export class PersistentCacheIndexManager {
38+
readonly type: 'PersistentCacheIndexManager' = 'PersistentCacheIndexManager';
39+
40+
/** @hideconstructor */
41+
constructor(readonly _client: FirestoreClient) {}
42+
}
43+
44+
/**
45+
* Returns the PersistentCache Index Manager used by the given `Firestore`
46+
* object.
47+
*
48+
* @return The `PersistentCacheIndexManager` instance, or `null` if local
49+
* persistent storage is not in use.
50+
*
51+
* TODO(CSI) Remove @internal to make the API publicly available.
52+
* @internal
53+
*/
54+
export function getPersistentCacheIndexManager(
55+
firestore: Firestore
56+
): PersistentCacheIndexManager | null {
57+
firestore = cast(firestore, Firestore);
58+
59+
const cachedInstance = persistentCacheIndexManagerByFirestore.get(firestore);
60+
if (cachedInstance) {
61+
return cachedInstance;
62+
}
63+
64+
const client = ensureFirestoreConfigured(firestore);
65+
if (client._uninitializedComponentsProvider?._offlineKind !== 'persistent') {
66+
return null;
67+
}
68+
69+
const instance = new PersistentCacheIndexManager(client);
70+
persistentCacheIndexManagerByFirestore.set(firestore, instance);
71+
return instance;
72+
}
73+
74+
/**
75+
* Enables SDK to create persistent cache indexes automatically for local query
76+
* execution when SDK believes cache indexes can help improves performance.
77+
*
78+
* This feature is disabled by default.
79+
*
80+
* TODO(CSI) Remove @internal to make the API publicly available.
81+
* @internal
82+
*/
83+
export function enablePersistentCacheIndexAutoCreation(
84+
indexManager: PersistentCacheIndexManager
85+
): void {
86+
setPersistentCacheIndexAutoCreationEnabled(indexManager, true);
87+
}
88+
89+
/**
90+
* Stops creating persistent cache indexes automatically for local query
91+
* execution. The indexes which have been created by calling
92+
* `enablePersistentCacheIndexAutoCreation()` still take effect.
93+
*
94+
* TODO(CSI) Remove @internal to make the API publicly available.
95+
* @internal
96+
*/
97+
export function disablePersistentCacheIndexAutoCreation(
98+
indexManager: PersistentCacheIndexManager
99+
): void {
100+
setPersistentCacheIndexAutoCreationEnabled(indexManager, false);
101+
}
102+
103+
/**
104+
* Removes all persistent cache indexes.
105+
*
106+
* Please note this function will also deletes indexes generated by
107+
* `setIndexConfiguration()`, which is deprecated.
108+
*
109+
* TODO(CSI) Remove @internal to make the API publicly available.
110+
* @internal
111+
*/
112+
export function deleteAllPersistentCacheIndexes(
113+
indexManager: PersistentCacheIndexManager
114+
): void {
115+
indexManager._client.verifyNotTerminated();
116+
117+
const promise = firestoreClientDeleteAllFieldIndexes(indexManager._client);
118+
119+
promise
120+
.then(_ => logDebug('deleting all persistent cache indexes succeeded'))
121+
.catch(error =>
122+
logWarn('deleting all persistent cache indexes failed', error)
123+
);
124+
}
125+
126+
function setPersistentCacheIndexAutoCreationEnabled(
127+
indexManager: PersistentCacheIndexManager,
128+
isEnabled: boolean
129+
): void {
130+
indexManager._client.verifyNotTerminated();
131+
132+
const promise = firestoreClientSetPersistentCacheIndexAutoCreationEnabled(
133+
indexManager._client,
134+
isEnabled
135+
);
136+
137+
promise
138+
.then(_ =>
139+
logDebug(
140+
`setting persistent cache index auto creation ` +
141+
`isEnabled=${isEnabled} succeeded`
142+
)
143+
)
144+
.catch(error =>
145+
logWarn(
146+
`setting persistent cache index auto creation ` +
147+
`isEnabled=${isEnabled} failed`,
148+
error
149+
)
150+
);
151+
}
152+
153+
/**
154+
* Maps `Firestore` instances to their corresponding
155+
* `PersistentCacheIndexManager` instances.
156+
*
157+
* Use a `WeakMap` so that the mapping will be automatically dropped when the
158+
* `Firestore` instance is garbage collected. This emulates a private member
159+
* as described in https://goo.gle/454yvug.
160+
*/
161+
const persistentCacheIndexManagerByFirestore = new WeakMap<
162+
Firestore,
163+
PersistentCacheIndexManager
164+
>();

packages/firestore/src/core/firestore_client.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@ import { User } from '../auth/user';
2626
import { LocalStore } from '../local/local_store';
2727
import {
2828
localStoreConfigureFieldIndexes,
29+
localStoreDeleteAllFieldIndexes,
2930
localStoreExecuteQuery,
3031
localStoreGetNamedQuery,
3132
localStoreHandleUserChange,
32-
localStoreReadDocument
33+
localStoreReadDocument,
34+
localStoreSetIndexAutoCreationEnabled
3335
} from '../local/local_store_impl';
3436
import { Persistence } from '../local/persistence';
3537
import { Document } from '../model/document';
@@ -828,3 +830,23 @@ export function firestoreClientSetIndexConfiguration(
828830
);
829831
});
830832
}
833+
834+
export function firestoreClientSetPersistentCacheIndexAutoCreationEnabled(
835+
client: FirestoreClient,
836+
isEnabled: boolean
837+
): Promise<void> {
838+
return client.asyncQueue.enqueue(async () => {
839+
return localStoreSetIndexAutoCreationEnabled(
840+
await getLocalStore(client),
841+
isEnabled
842+
);
843+
});
844+
}
845+
846+
export function firestoreClientDeleteAllFieldIndexes(
847+
client: FirestoreClient
848+
): Promise<void> {
849+
return client.asyncQueue.enqueue(async () => {
850+
return localStoreDeleteAllFieldIndexes(await getLocalStore(client));
851+
});
852+
}

packages/firestore/src/local/index_manager.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,19 @@ export const enum IndexType {
4141
FULL
4242
}
4343

44+
export function displayNameForIndexType(indexType: IndexType): string {
45+
switch (indexType) {
46+
case IndexType.NONE:
47+
return 'NONE';
48+
case IndexType.PARTIAL:
49+
return 'PARTIAL';
50+
case IndexType.FULL:
51+
return 'FULL';
52+
default:
53+
return `[unknown IndexType: ${indexType}]`;
54+
}
55+
}
56+
4457
/**
4558
* Represents a set of indexes that are used to execute queries efficiently.
4659
*
@@ -92,6 +105,17 @@ export interface IndexManager {
92105
index: FieldIndex
93106
): PersistencePromise<void>;
94107

108+
/** Removes all field indexes and deletes all index values. */
109+
deleteAllFieldIndexes(
110+
transaction: PersistenceTransaction
111+
): PersistencePromise<void>;
112+
113+
/** Creates a full matched field index which serves the given target. */
114+
createTargetIndexes(
115+
transaction: PersistenceTransaction,
116+
target: Target
117+
): PersistencePromise<void>;
118+
95119
/**
96120
* Returns a list of field indexes that correspond to the specified collection
97121
* group.

0 commit comments

Comments
 (0)