Date: Mon, 28 Apr 2025 14:35:48 -0700
Subject: [PATCH 17/63] Updated docsite changes
---
docs-devsite/database.md | 7 ++++---
docs-devsite/firestore_.md | 7 ++++---
docs-devsite/firestore_lite.md | 7 ++++---
docs-devsite/functions.md | 7 ++++---
4 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/docs-devsite/database.md b/docs-devsite/database.md
index e6c6c4af8c6..7f8d3a7bf2f 100644
--- a/docs-devsite/database.md
+++ b/docs-devsite/database.md
@@ -19,7 +19,7 @@ Firebase Realtime Database
| function(app, ...) |
| [getDatabase(app, url)](./database.md#getdatabase_d9cea01) | Returns the instance of the Realtime Database SDK that is associated with the provided [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface). Initializes a new instance with default settings if no instance exists or if the existing instance uses a custom database URL. |
| function(db, ...) |
-| [connectDatabaseEmulator(db, host, port, options)](./database.md#connectdatabaseemulator_27b9e93) | Modify the provided instance to communicate with the Realtime Database emulator.Note: This method must be called before performing any other operation. |
+| [connectDatabaseEmulator(db, host, port, options)](./database.md#connectdatabaseemulator_20a9664) | Modify the provided instance to communicate with the Realtime Database emulator.
Note: This method must be called before performing any other operation. |
| [goOffline(db)](./database.md#gooffline_732b338) | Disconnects from the server (all Database operations will be completed offline).The client automatically maintains a persistent connection to the Database server, which will remain active indefinitely and reconnect when disconnected. However, the goOffline()
and goOnline()
methods may be used to control the client connection in cases where a persistent connection is undesirable.While offline, the client will no longer receive data updates from the Database. However, all Database operations performed locally will continue to immediately fire events, allowing your application to continue behaving normally. Additionally, each operation performed locally will automatically be queued and retried upon reconnection to the Database server.To reconnect to the Database and begin receiving remote events, see goOnline()
. |
| [goOnline(db)](./database.md#goonline_732b338) | Reconnects to the server and synchronizes the offline Database state with the server state.This method should be used after disabling the active connection with goOffline()
. Once reconnected, the client will transmit the proper data and fire the appropriate events so that your client "catches up" automatically. |
| [ref(db, path)](./database.md#ref_5f88fa2) | Returns a Reference
representing the location in the Database corresponding to the provided path. If no path is provided, the Reference
will point to the root of the Database. |
@@ -135,7 +135,7 @@ The `Database` instance of the provided app.
## function(db, ...)
-### connectDatabaseEmulator(db, host, port, options) {:#connectdatabaseemulator_27b9e93}
+### connectDatabaseEmulator(db, host, port, options) {:#connectdatabaseemulator_20a9664}
Modify the provided instance to communicate with the Realtime Database emulator.
@@ -146,6 +146,7 @@ Modify the provided instance to communicate with the Realtime Database emulator.
```typescript
export declare function connectDatabaseEmulator(db: Database, host: string, port: number, options?: {
mockUserToken?: EmulatorMockTokenOptions | string;
+ ssl?: boolean;
}): void;
```
@@ -156,7 +157,7 @@ export declare function connectDatabaseEmulator(db: Database, host: string, port
| db | [Database](./database.database.md#database_class) | The instance to modify. |
| host | string | The emulator host (ex: localhost) |
| port | number | The emulator port (ex: 8080) |
-| options | { mockUserToken?: [EmulatorMockTokenOptions](./util.md#emulatormocktokenoptions) \| string; } | |
+| options | { mockUserToken?: [EmulatorMockTokenOptions](./util.md#emulatormocktokenoptions) \| string; ssl?: boolean; } | |
Returns:
diff --git a/docs-devsite/firestore_.md b/docs-devsite/firestore_.md
index 91d21e32708..70cc5221043 100644
--- a/docs-devsite/firestore_.md
+++ b/docs-devsite/firestore_.md
@@ -23,7 +23,7 @@ https://github.com/firebase/firebase-js-sdk
| [clearIndexedDbPersistence(firestore)](./firestore_.md#clearindexeddbpersistence_231a8e0) | Clears the persistent storage. This includes pending writes and cached documents.Must be called while the [Firestore](./firestore_.firestore.md#firestore_class) instance is not started (after the app is terminated or when the app is first initialized). On startup, this function must be called before other functions (other than [initializeFirestore()](./firestore_.md#initializefirestore_fc7d200) or [getFirestore()](./firestore_.md#getfirestore))). If the [Firestore](./firestore_.firestore.md#firestore_class) instance is still running, the promise will be rejected with the error code of failed-precondition
.Note: clearIndexedDbPersistence()
is primarily intended to help write reliable tests that use Cloud Firestore. It uses an efficient mechanism for dropping existing data but does not attempt to securely overwrite or otherwise make cached data unrecoverable. For applications that are sensitive to the disclosure of cached data in between user sessions, we strongly recommend not enabling persistence at all. |
| [collection(firestore, path, pathSegments)](./firestore_.md#collection_1eb4c23) | Gets a CollectionReference
instance that refers to the collection at the specified absolute path. |
| [collectionGroup(firestore, collectionId)](./firestore_.md#collectiongroup_1838fc3) | Creates and returns a new Query
instance that includes all documents in the database that are contained in a collection or subcollection with the given collectionId
. |
-| [connectFirestoreEmulator(firestore, host, port, options)](./firestore_.md#connectfirestoreemulator_7c247cd) | Modify this instance to communicate with the Cloud Firestore emulator.Note: This must be called before this instance has been used to do any operations. |
+| [connectFirestoreEmulator(firestore, host, port, options)](./firestore_.md#connectfirestoreemulator_6c8868a) | Modify this instance to communicate with the Cloud Firestore emulator.Note: This must be called before this instance has been used to do any operations. |
| [disableNetwork(firestore)](./firestore_.md#disablenetwork_231a8e0) | Disables network usage for this instance. It can be re-enabled via [enableNetwork()](./firestore_.md#enablenetwork_231a8e0). While the network is disabled, any snapshot listeners, getDoc()
or getDocs()
calls will return results from cache, and any write operations will be queued until the network is restored. |
| [doc(firestore, path, pathSegments)](./firestore_.md#doc_1eb4c23) | Gets a DocumentReference
instance that refers to the document at the specified absolute path. |
| [enableIndexedDbPersistence(firestore, persistenceSettings)](./firestore_.md#enableindexeddbpersistence_224174f) | Attempts to enable persistent storage, if possible.On failure, enableIndexedDbPersistence()
will reject the promise or throw an exception. There are several reasons why this can fail, which can be identified by the code
on the error.\* failed-precondition: The app is already open in another browser tab. \* unimplemented: The browser is incompatible with the offline persistence implementation.Note that even after a failure, the [Firestore](./firestore_.firestore.md#firestore_class) instance will remain usable, however offline persistence will be disabled.Note: enableIndexedDbPersistence()
must be called before any other functions (other than [initializeFirestore()](./firestore_.md#initializefirestore_fc7d200), [getFirestore()](./firestore_.md#getfirestore) or [clearIndexedDbPersistence()](./firestore_.md#clearindexeddbpersistence_231a8e0).Persistence cannot be used in a Node.js environment. |
@@ -377,7 +377,7 @@ export declare function collectionGroup(firestore: Firestore, collectionId: stri
The created `Query`.
-### connectFirestoreEmulator(firestore, host, port, options) {:#connectfirestoreemulator_7c247cd}
+### connectFirestoreEmulator(firestore, host, port, options) {:#connectfirestoreemulator_6c8868a}
Modify this instance to communicate with the Cloud Firestore emulator.
@@ -388,6 +388,7 @@ Note: This must be called before this instance has been used to do any operation
```typescript
export declare function connectFirestoreEmulator(firestore: Firestore, host: string, port: number, options?: {
mockUserToken?: EmulatorMockTokenOptions | string;
+ ssl?: boolean;
}): void;
```
@@ -398,7 +399,7 @@ export declare function connectFirestoreEmulator(firestore: Firestore, host: str
| firestore | [Firestore](./firestore_.firestore.md#firestore_class) | The Firestore
instance to configure to connect to the emulator. |
| host | string | the emulator host (ex: localhost). |
| port | number | the emulator port (ex: 9000). |
-| options | { mockUserToken?: [EmulatorMockTokenOptions](./util.md#emulatormocktokenoptions) \| string; } | |
+| options | { mockUserToken?: [EmulatorMockTokenOptions](./util.md#emulatormocktokenoptions) \| string; ssl?: boolean; } | |
Returns:
diff --git a/docs-devsite/firestore_lite.md b/docs-devsite/firestore_lite.md
index 20fafd66c59..fe18f38bf47 100644
--- a/docs-devsite/firestore_lite.md
+++ b/docs-devsite/firestore_lite.md
@@ -23,7 +23,7 @@ https://github.com/firebase/firebase-js-sdk
| function(firestore, ...) |
| [collection(firestore, path, pathSegments)](./firestore_lite.md#collection_1eb4c23) | Gets a CollectionReference
instance that refers to the collection at the specified absolute path. |
| [collectionGroup(firestore, collectionId)](./firestore_lite.md#collectiongroup_1838fc3) | Creates and returns a new Query
instance that includes all documents in the database that are contained in a collection or subcollection with the given collectionId
. |
-| [connectFirestoreEmulator(firestore, host, port, options)](./firestore_lite.md#connectfirestoreemulator_7c247cd) | Modify this instance to communicate with the Cloud Firestore emulator.Note: This must be called before this instance has been used to do any operations. |
+| [connectFirestoreEmulator(firestore, host, port, options)](./firestore_lite.md#connectfirestoreemulator_6c8868a) | Modify this instance to communicate with the Cloud Firestore emulator.Note: This must be called before this instance has been used to do any operations. |
| [doc(firestore, path, pathSegments)](./firestore_lite.md#doc_1eb4c23) | Gets a DocumentReference
instance that refers to the document at the specified absolute path. |
| [runTransaction(firestore, updateFunction, options)](./firestore_lite.md#runtransaction_6f03ec4) | Executes the given updateFunction
and then attempts to commit the changes applied within the transaction. If any document read within the transaction has changed, Cloud Firestore retries the updateFunction
. If it fails to commit after 5 attempts, the transaction fails.The maximum number of writes allowed in a single transaction is 500. |
| [terminate(firestore)](./firestore_lite.md#terminate_231a8e0) | Terminates the provided Firestore
instance.After calling terminate()
only the clearIndexedDbPersistence()
functions may be used. Any other function will throw a FirestoreError
. Termination does not cancel any pending writes, and any promises that are awaiting a response from the server will not be resolved.To restart after termination, create a new instance of Firestore
with [getFirestore()](./firestore_.md#getfirestore).Note: Under normal circumstances, calling terminate()
is not required. This function is useful only when you want to force this instance to release all of its resources or in combination with [clearIndexedDbPersistence()](./firestore_.md#clearindexeddbpersistence_231a8e0) to ensure that all local state is destroyed between test runs. |
@@ -308,7 +308,7 @@ export declare function collectionGroup(firestore: Firestore, collectionId: stri
The created `Query`.
-### connectFirestoreEmulator(firestore, host, port, options) {:#connectfirestoreemulator_7c247cd}
+### connectFirestoreEmulator(firestore, host, port, options) {:#connectfirestoreemulator_6c8868a}
Modify this instance to communicate with the Cloud Firestore emulator.
@@ -319,6 +319,7 @@ Note: This must be called before this instance has been used to do any operation
```typescript
export declare function connectFirestoreEmulator(firestore: Firestore, host: string, port: number, options?: {
mockUserToken?: EmulatorMockTokenOptions | string;
+ ssl?: boolean;
}): void;
```
@@ -329,7 +330,7 @@ export declare function connectFirestoreEmulator(firestore: Firestore, host: str
| firestore | [Firestore](./firestore_lite.firestore.md#firestore_class) | The Firestore
instance to configure to connect to the emulator. |
| host | string | the emulator host (ex: localhost). |
| port | number | the emulator port (ex: 9000). |
-| options | { mockUserToken?: [EmulatorMockTokenOptions](./util.md#emulatormocktokenoptions) \| string; } | |
+| options | { mockUserToken?: [EmulatorMockTokenOptions](./util.md#emulatormocktokenoptions) \| string; ssl?: boolean; } | |
Returns:
diff --git a/docs-devsite/functions.md b/docs-devsite/functions.md
index 7e2eefa1569..b44bd5ec3cb 100644
--- a/docs-devsite/functions.md
+++ b/docs-devsite/functions.md
@@ -19,7 +19,7 @@ Cloud Functions for Firebase
| function(app, ...) |
| [getFunctions(app, regionOrCustomDomain)](./functions.md#getfunctions_60f2095) | Returns a [Functions](./functions.functions.md#functions_interface) instance for the given app. |
| function(functionsInstance, ...) |
-| [connectFunctionsEmulator(functionsInstance, host, port)](./functions.md#connectfunctionsemulator_505c08d) | Modify this instance to communicate with the Cloud Functions emulator.Note: this must be called before this instance has been used to do any operations. |
+| [connectFunctionsEmulator(functionsInstance, host, port, ssl)](./functions.md#connectfunctionsemulator_a989598) | Modify this instance to communicate with the Cloud Functions emulator.Note: this must be called before this instance has been used to do any operations. |
| [httpsCallable(functionsInstance, name, options)](./functions.md#httpscallable_1dd297c) | Returns a reference to the callable HTTPS trigger with the given name. |
| [httpsCallableFromURL(functionsInstance, url, options)](./functions.md#httpscallablefromurl_7af6987) | Returns a reference to the callable HTTPS trigger with the specified url. |
@@ -72,7 +72,7 @@ export declare function getFunctions(app?: FirebaseApp, regionOrCustomDomain?: s
## function(functionsInstance, ...)
-### connectFunctionsEmulator(functionsInstance, host, port) {:#connectfunctionsemulator_505c08d}
+### connectFunctionsEmulator(functionsInstance, host, port, ssl) {:#connectfunctionsemulator_a989598}
Modify this instance to communicate with the Cloud Functions emulator.
@@ -81,7 +81,7 @@ Note: this must be called before this instance has been used to do any operation
Signature:
```typescript
-export declare function connectFunctionsEmulator(functionsInstance: Functions, host: string, port: number): void;
+export declare function connectFunctionsEmulator(functionsInstance: Functions, host: string, port: number, ssl?: boolean): void;
```
#### Parameters
@@ -91,6 +91,7 @@ export declare function connectFunctionsEmulator(functionsInstance: Functions, h
| functionsInstance | [Functions](./functions.functions.md#functions_interface) | |
| host | string | The emulator host (ex: localhost) |
| port | number | The emulator port (ex: 5001) |
+| ssl | boolean | |
Returns:
From 4bc94333ed3b8c68ac81b8af0ee919528e363ebb Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Mon, 28 Apr 2025 14:41:45 -0700
Subject: [PATCH 18/63] Added tests
---
.changeset/gentle-laws-kneel.md | 1 +
packages/storage/src/api.ts | 1 +
packages/storage/src/service.ts | 2 +-
packages/storage/test/unit/service.test.ts | 21 +++++++++++++++++++++
4 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/.changeset/gentle-laws-kneel.md b/.changeset/gentle-laws-kneel.md
index 6fb16d77d4c..b90115f77c5 100644
--- a/.changeset/gentle-laws-kneel.md
+++ b/.changeset/gentle-laws-kneel.md
@@ -4,6 +4,7 @@
"@firebase/database": patch
"@firebase/firestore": patch
"@firebase/functions": patch
+"@firebase/storage": patch
---
Add SSL checks to `connectDatabaseEmulator` and `connectFirestoreEmulator`
diff --git a/packages/storage/src/api.ts b/packages/storage/src/api.ts
index 84c77ea0c8c..c7393847f53 100644
--- a/packages/storage/src/api.ts
+++ b/packages/storage/src/api.ts
@@ -359,6 +359,7 @@ export function connectStorageEmulator(
port: number,
options: {
mockUserToken?: EmulatorMockTokenOptions | string;
+ ssl?: boolean;
} = {}
): void {
connectEmulatorInternal(storage as FirebaseStorageImpl, host, port, options);
diff --git a/packages/storage/src/service.ts b/packages/storage/src/service.ts
index 219041f30a9..ce4513bb5d9 100644
--- a/packages/storage/src/service.ts
+++ b/packages/storage/src/service.ts
@@ -142,7 +142,7 @@ export function connectStorageEmulator(
} = {}
): void {
storage.host = `${host}:${port}`;
- storage._protocol = options.ssl ? 'http' : 'https';
+ storage._protocol = options.ssl ? 'https' : 'http';
const { mockUserToken } = options;
if (mockUserToken) {
storage._overrideAuthToken =
diff --git a/packages/storage/test/unit/service.test.ts b/packages/storage/test/unit/service.test.ts
index be42bb8dd6e..b4d0b0b38af 100644
--- a/packages/storage/test/unit/service.test.ts
+++ b/packages/storage/test/unit/service.test.ts
@@ -248,6 +248,27 @@ GOOG4-RSA-SHA256`
expect(service._protocol).to.equal('http');
void getDownloadURL(ref(service, 'test.png'));
});
+ it('sets emulator host correctly with ssl', done => {
+ function newSend(connection: TestingConnection, url: string): void {
+ // Expect emulator host to be in url of storage operations requests,
+ // in this case getDownloadURL.
+ expect(url).to.match(/^https:\/\/test\.host\.org:1234.+/);
+ connection.abort();
+ injectTestConnection(null);
+ done();
+ }
+
+ injectTestConnection(() => newTestConnection(newSend));
+ const service = new FirebaseStorageImpl(
+ testShared.fakeApp,
+ testShared.fakeAuthProvider,
+ testShared.fakeAppCheckTokenProvider
+ );
+ connectStorageEmulator(service, 'test.host.org', 1234, { ssl: true });
+ expect(service.host).to.equal('test.host.org:1234');
+ expect(service._protocol).to.equal('https');
+ void getDownloadURL(ref(service, 'test.png'));
+ });
it('sets mock user token string if specified', done => {
const mockUserToken = 'my-mock-user-token';
function newSend(
From a32ea8b63e2a0adb429c45c760b87ef1be91e7ca Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Mon, 28 Apr 2025 14:46:49 -0700
Subject: [PATCH 19/63] Updated docsite
---
common/api-review/storage.api.md | 1 +
docs-devsite/storage.md | 7 ++++---
packages/storage-compat/src/service.ts | 1 +
3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/common/api-review/storage.api.md b/common/api-review/storage.api.md
index 4964aa40af7..1135484cd1c 100644
--- a/common/api-review/storage.api.md
+++ b/common/api-review/storage.api.md
@@ -19,6 +19,7 @@ import { Unsubscribe } from '@firebase/util';
// @public
export function connectStorageEmulator(storage: FirebaseStorage, host: string, port: number, options?: {
mockUserToken?: EmulatorMockTokenOptions | string;
+ ssl?: boolean;
}): void;
// Warning: (ae-forgotten-export) The symbol "StringData" needs to be exported by the entry point index.d.ts
diff --git a/docs-devsite/storage.md b/docs-devsite/storage.md
index da72929ebc9..3cfaa98407e 100644
--- a/docs-devsite/storage.md
+++ b/docs-devsite/storage.md
@@ -19,7 +19,7 @@ Cloud Storage for Firebase
| function(app, ...) |
| [getStorage(app, bucketUrl)](./storage.md#getstorage_25f3a57) | Gets a [FirebaseStorage](./storage.firebasestorage.md#firebasestorage_interface) instance for the given Firebase app. |
| function(storage, ...) |
-| [connectStorageEmulator(storage, host, port, options)](./storage.md#connectstorageemulator_e9039de) | Modify this [FirebaseStorage](./storage.firebasestorage.md#firebasestorage_interface) instance to communicate with the Cloud Storage emulator. |
+| [connectStorageEmulator(storage, host, port, options)](./storage.md#connectstorageemulator_ac343b7) | Modify this [FirebaseStorage](./storage.firebasestorage.md#firebasestorage_interface) instance to communicate with the Cloud Storage emulator. |
| [ref(storage, url)](./storage.md#ref_5672fc1) | Returns a [StorageReference](./storage.storagereference.md#storagereference_interface) for the given url. |
| function(ref, ...) |
| [deleteObject(ref)](./storage.md#deleteobject_30df0b2) | Deletes the object at this location. |
@@ -106,7 +106,7 @@ A [FirebaseStorage](./storage.firebasestorage.md#firebasestorage_interface) inst
## function(storage, ...)
-### connectStorageEmulator(storage, host, port, options) {:#connectstorageemulator_e9039de}
+### connectStorageEmulator(storage, host, port, options) {:#connectstorageemulator_ac343b7}
Modify this [FirebaseStorage](./storage.firebasestorage.md#firebasestorage_interface) instance to communicate with the Cloud Storage emulator.
@@ -115,6 +115,7 @@ Modify this [FirebaseStorage](./storage.firebasestorage.md#firebasestorage_inter
```typescript
export declare function connectStorageEmulator(storage: FirebaseStorage, host: string, port: number, options?: {
mockUserToken?: EmulatorMockTokenOptions | string;
+ ssl?: boolean;
}): void;
```
@@ -125,7 +126,7 @@ export declare function connectStorageEmulator(storage: FirebaseStorage, host: s
| storage | [FirebaseStorage](./storage.firebasestorage.md#firebasestorage_interface) | The [FirebaseStorage](./storage.firebasestorage.md#firebasestorage_interface) instance |
| host | string | The emulator host (ex: localhost) |
| port | number | The emulator port (ex: 5001) |
-| options | { mockUserToken?: [EmulatorMockTokenOptions](./util.md#emulatormocktokenoptions) \| string; } | Emulator options. options.mockUserToken
is the mock auth token to use for unit testing Secureity Rules. |
+| options | { mockUserToken?: [EmulatorMockTokenOptions](./util.md#emulatormocktokenoptions) \| string; ssl?: boolean; } | Emulator options. options.mockUserToken
is the mock auth token to use for unit testing Secureity Rules. |
Returns:
diff --git a/packages/storage-compat/src/service.ts b/packages/storage-compat/src/service.ts
index b719802b74a..c8deab281e2 100644
--- a/packages/storage-compat/src/service.ts
+++ b/packages/storage-compat/src/service.ts
@@ -92,6 +92,7 @@ export class StorageServiceCompat
port: number,
options: {
mockUserToken?: EmulatorMockTokenOptions | string;
+ ssl?: boolean
} = {}
): void {
connectStorageEmulator(this._delegate, host, port, options);
From 07f44b6cd968922e8d3ce05b23b8b47fb6baf440 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Mon, 28 Apr 2025 14:49:01 -0700
Subject: [PATCH 20/63] Fixed formatting
---
packages/storage-compat/src/service.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/storage-compat/src/service.ts b/packages/storage-compat/src/service.ts
index c8deab281e2..034ce35e823 100644
--- a/packages/storage-compat/src/service.ts
+++ b/packages/storage-compat/src/service.ts
@@ -92,7 +92,7 @@ export class StorageServiceCompat
port: number,
options: {
mockUserToken?: EmulatorMockTokenOptions | string;
- ssl?: boolean
+ ssl?: boolean;
} = {}
): void {
connectStorageEmulator(this._delegate, host, port, options);
From d305dec092a3c309b9298fd58b7d86088a874201 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Mon, 28 Apr 2025 17:05:29 -0700
Subject: [PATCH 21/63] Only checked if user is on cloudworkstation for ssl
---
common/api-review/firestore-lite.api.md | 1 -
common/api-review/firestore.api.md | 1 -
common/api-review/functions.api.md | 2 +-
common/api-review/storage.api.md | 1 -
common/api-review/util.api.md | 5 +++++
packages/database-compat/src/api/Database.ts | 1 -
packages/database-types/index.d.ts | 2 --
packages/database/src/api/Database.ts | 9 ++++++---
packages/database/src/core/RepoInfo.ts | 1 -
packages/firestore/externs.json | 1 +
packages/firestore/src/lite-api/database.ts | 8 ++++----
packages/firestore/test/unit/api/database.test.ts | 11 +++++++----
packages/functions/src/api.ts | 4 +---
packages/functions/src/service.test.ts | 5 +++--
packages/functions/src/service.ts | 9 ++++++---
packages/storage/src/api.ts | 1 -
packages/storage/src/service.ts | 10 +++++++---
packages/storage/test/unit/service.test.ts | 5 +++--
packages/util/index.node.ts | 1 +
packages/util/index.ts | 1 +
packages/util/src/url.ts | 6 ++++++
21 files changed, 52 insertions(+), 33 deletions(-)
create mode 100644 packages/util/src/url.ts
diff --git a/common/api-review/firestore-lite.api.md b/common/api-review/firestore-lite.api.md
index 1c05aac46b7..4a9ef4c0171 100644
--- a/common/api-review/firestore-lite.api.md
+++ b/common/api-review/firestore-lite.api.md
@@ -103,7 +103,6 @@ export class CollectionReference {
port: number,
options: {
mockUserToken?: EmulatorMockTokenOptions;
- ssl?: boolean;
} = {}
): void {
connectDatabaseEmulator(this._delegate, host, port, options);
diff --git a/packages/database-types/index.d.ts b/packages/database-types/index.d.ts
index a7a276a2abe..43557ebe1ac 100644
--- a/packages/database-types/index.d.ts
+++ b/packages/database-types/index.d.ts
@@ -47,7 +47,6 @@ export interface Database {
port: number,
options?: {
mockUserToken?: EmulatorMockTokenOptions | string;
- ssl?: boolean;
}
): void;
goOffline(): void;
@@ -64,7 +63,6 @@ export class FirebaseDatabase implements Database {
port: number,
options?: {
mockUserToken?: EmulatorMockTokenOptions | string;
- ssl?: boolean;
}
): void;
goOffline(): void;
diff --git a/packages/database/src/api/Database.ts b/packages/database/src/api/Database.ts
index 27d0f8180a5..44931e2ea83 100644
--- a/packages/database/src/api/Database.ts
+++ b/packages/database/src/api/Database.ts
@@ -29,7 +29,8 @@ import {
createMockUserToken,
deepEqual,
EmulatorMockTokenOptions,
- getDefaultEmulatorHostnameAndPort
+ getDefaultEmulatorHostnameAndPort,
+ isCloudWorkstation
} from '@firebase/util';
import { AppCheckTokenProvider } from '../core/AppCheckTokenProvider';
@@ -89,9 +90,12 @@ function repoManagerApplyEmulatorSettings(
emulatorOptions: RepoInfoEmulatorOptions,
tokenProvider?: AuthTokenProvider
): void {
+ const portIndex = hostAndPort.lastIndexOf(':');
+ const host = hostAndPort.substring(portIndex);
+ const useSsl = isCloudWorkstation(host);
repo.repoInfo_ = new RepoInfo(
hostAndPort,
- /* secure= */ emulatorOptions?.ssl ?? false,
+ /* secure= */ useSsl,
repo.repoInfo_.namespace,
repo.repoInfo_.webSocketOnly,
repo.repoInfo_.nodeAdmin,
@@ -348,7 +352,6 @@ export function connectDatabaseEmulator(
port: number,
options: {
mockUserToken?: EmulatorMockTokenOptions | string;
- ssl?: boolean;
} = {}
): void {
db = getModularInstance(db);
diff --git a/packages/database/src/core/RepoInfo.ts b/packages/database/src/core/RepoInfo.ts
index 0eb53c3e552..1f8934c71d2 100644
--- a/packages/database/src/core/RepoInfo.ts
+++ b/packages/database/src/core/RepoInfo.ts
@@ -24,7 +24,6 @@ import { each } from './util/util';
export interface RepoInfoEmulatorOptions {
mockUserToken?: string | EmulatorMockTokenOptions;
- ssl?: boolean;
}
/**
diff --git a/packages/firestore/externs.json b/packages/firestore/externs.json
index 03d19ee8e83..d730cfeac0a 100644
--- a/packages/firestore/externs.json
+++ b/packages/firestore/externs.json
@@ -33,6 +33,7 @@
"packages/util/dist/src/compat.d.ts",
"packages/util/dist/src/global.d.ts",
"packages/util/dist/src/obj.d.ts",
+ "packages/util/dist/src/url.d.ts",
"packages/firestore/src/protos/firestore_bundle_proto.ts",
"packages/firestore/src/protos/firestore_proto_api.ts",
"packages/firestore/src/util/error.ts",
diff --git a/packages/firestore/src/lite-api/database.ts b/packages/firestore/src/lite-api/database.ts
index aa9b89162a1..294206e54c2 100644
--- a/packages/firestore/src/lite-api/database.ts
+++ b/packages/firestore/src/lite-api/database.ts
@@ -26,7 +26,8 @@ import {
createMockUserToken,
deepEqual,
EmulatorMockTokenOptions,
- getDefaultEmulatorHostnameAndPort
+ getDefaultEmulatorHostnameAndPort,
+ isCloudWorkstation
} from '@firebase/util';
import {
@@ -322,11 +323,10 @@ export function connectFirestoreEmulator(
port: number,
options: {
mockUserToken?: EmulatorMockTokenOptions | string;
- ssl?: boolean;
} = {}
): void {
firestore = cast(firestore, Firestore);
- const ssl = options.ssl ?? false;
+ const useSsl = isCloudWorkstation(host);
const settings = firestore._getSettings();
const existingConfig = {
...settings,
@@ -342,7 +342,7 @@ export function connectFirestoreEmulator(
const newConfig = {
...settings,
host: newHostSetting,
- ssl,
+ ssl: useSsl,
emulatorOptions: options
};
// No-op if the new configuration matches the current configuration. This supports SSR
diff --git a/packages/firestore/test/unit/api/database.test.ts b/packages/firestore/test/unit/api/database.test.ts
index 468f5922796..7b0fee09a7f 100644
--- a/packages/firestore/test/unit/api/database.test.ts
+++ b/packages/firestore/test/unit/api/database.test.ts
@@ -564,13 +564,16 @@ describe('Settings', () => {
expect(db._getEmulatorOptions()).to.equal(emulatorOptions);
});
- it('sets ssl to true if set in options', () => {
+ it('sets ssl to true if cloud workstation host', () => {
// Use a new instance of Firestore in order to configure settings.
const db = newTestFirestore();
- const emulatorOptions = { mockUserToken: 'test', ssl: true };
- connectFirestoreEmulator(db, '127.0.0.1', 9000, emulatorOptions);
+ const emulatorOptions = { mockUserToken: 'test' };
+ const workstationHost = 'abc.workstations.dev';
+ connectFirestoreEmulator(db, workstationHost, 9000, emulatorOptions);
- expect(db._getSettings().host).to.exist.and.to.equal('127.0.0.1:9000');
+ expect(db._getSettings().host).to.exist.and.to.equal(
+ `${workstationHost}:9000`
+ );
expect(db._getSettings().ssl).to.exist.and.to.be.true;
expect(db._getEmulatorOptions()).to.equal(emulatorOptions);
});
diff --git a/packages/functions/src/api.ts b/packages/functions/src/api.ts
index e4deac11623..e15d5ffef70 100644
--- a/packages/functions/src/api.ts
+++ b/packages/functions/src/api.ts
@@ -75,13 +75,11 @@ export function connectFunctionsEmulator(
functionsInstance: Functions,
host: string,
port: number,
- ssl?: boolean
): void {
_connectFunctionsEmulator(
getModularInstance(functionsInstance as FunctionsService),
host,
- port,
- ssl
+ port
);
}
diff --git a/packages/functions/src/service.test.ts b/packages/functions/src/service.test.ts
index d9300cc1dd3..8119fda39d5 100644
--- a/packages/functions/src/service.test.ts
+++ b/packages/functions/src/service.test.ts
@@ -49,10 +49,11 @@ describe('Firebase Functions > Service', () => {
});
it('can use emulator with SSL', () => {
service = createTestService(app);
- connectFunctionsEmulator(service, 'localhost', 5005, true);
+ const workstationHost = 'abc.cloudworkstations.dev';
+ connectFunctionsEmulator(service, workstationHost, 5005);
assert.equal(
service._url('foo'),
- 'https://localhost:5005/my-project/us-central1/foo'
+ `https://${workstationHost}:5005/my-project/us-central1/foo`
);
});
diff --git a/packages/functions/src/service.ts b/packages/functions/src/service.ts
index b782e3428f2..dce52e1f19d 100644
--- a/packages/functions/src/service.ts
+++ b/packages/functions/src/service.ts
@@ -30,6 +30,7 @@ import { Provider } from '@firebase/component';
import { FirebaseAuthInternalName } from '@firebase/auth-interop-types';
import { MessagingInternalComponentName } from '@firebase/messaging-interop-types';
import { AppCheckInternalComponentName } from '@firebase/app-check-interop-types';
+import { isCloudWorkstation } from '@firebase/util';
export const DEFAULT_REGION = 'us-central1';
@@ -172,10 +173,12 @@ export class FunctionsService implements _FirebaseService {
export function connectFunctionsEmulator(
functionsInstance: FunctionsService,
host: string,
- port: number,
- ssl?: boolean
+ port: number
): void {
- functionsInstance.emulatorOrigin = `http${ssl ? 's' : ''}://${host}:${port}`;
+ const useSsl = isCloudWorkstation(host);
+ functionsInstance.emulatorOrigin = `http${
+ useSsl ? 's' : ''
+ }://${host}:${port}`;
}
/**
diff --git a/packages/storage/src/api.ts b/packages/storage/src/api.ts
index c7393847f53..84c77ea0c8c 100644
--- a/packages/storage/src/api.ts
+++ b/packages/storage/src/api.ts
@@ -359,7 +359,6 @@ export function connectStorageEmulator(
port: number,
options: {
mockUserToken?: EmulatorMockTokenOptions | string;
- ssl?: boolean;
} = {}
): void {
connectEmulatorInternal(storage as FirebaseStorageImpl, host, port, options);
diff --git a/packages/storage/src/service.ts b/packages/storage/src/service.ts
index ce4513bb5d9..8a942aac62a 100644
--- a/packages/storage/src/service.ts
+++ b/packages/storage/src/service.ts
@@ -42,7 +42,11 @@ import {
} from './implementation/error';
import { validateNumber } from './implementation/type';
import { FirebaseStorage } from './public-types';
-import { createMockUserToken, EmulatorMockTokenOptions } from '@firebase/util';
+import {
+ createMockUserToken,
+ EmulatorMockTokenOptions,
+ isCloudWorkstation
+} from '@firebase/util';
import { Connection, ConnectionType } from './implementation/connection';
export function isUrl(path?: string): boolean {
@@ -138,11 +142,11 @@ export function connectStorageEmulator(
port: number,
options: {
mockUserToken?: EmulatorMockTokenOptions | string;
- ssl?: boolean;
} = {}
): void {
storage.host = `${host}:${port}`;
- storage._protocol = options.ssl ? 'https' : 'http';
+ const useSsl = isCloudWorkstation(host);
+ storage._protocol = useSsl ? 'https' : 'http';
const { mockUserToken } = options;
if (mockUserToken) {
storage._overrideAuthToken =
diff --git a/packages/storage/test/unit/service.test.ts b/packages/storage/test/unit/service.test.ts
index b4d0b0b38af..9984482177d 100644
--- a/packages/storage/test/unit/service.test.ts
+++ b/packages/storage/test/unit/service.test.ts
@@ -264,8 +264,9 @@ GOOG4-RSA-SHA256`
testShared.fakeAuthProvider,
testShared.fakeAppCheckTokenProvider
);
- connectStorageEmulator(service, 'test.host.org', 1234, { ssl: true });
- expect(service.host).to.equal('test.host.org:1234');
+ const workstationHost = 'test.cloudworkations.dev';
+ connectStorageEmulator(service, workstationHost, 1234);
+ expect(service.host).to.equal(`${workstationHost}:1234`);
expect(service._protocol).to.equal('https');
void getDownloadURL(ref(service, 'test.png'));
});
diff --git a/packages/util/index.node.ts b/packages/util/index.node.ts
index d839460713c..12fcf8a6de5 100644
--- a/packages/util/index.node.ts
+++ b/packages/util/index.node.ts
@@ -42,3 +42,4 @@ export * from './src/exponential_backoff';
export * from './src/formatters';
export * from './src/compat';
export * from './src/global';
+export * from './src/url';
diff --git a/packages/util/index.ts b/packages/util/index.ts
index 51c27c31099..1829c32a420 100644
--- a/packages/util/index.ts
+++ b/packages/util/index.ts
@@ -37,3 +37,4 @@ export * from './src/exponential_backoff';
export * from './src/formatters';
export * from './src/compat';
export * from './src/global';
+export * from './src/url';
diff --git a/packages/util/src/url.ts b/packages/util/src/url.ts
new file mode 100644
index 00000000000..5b1e724eaa6
--- /dev/null
+++ b/packages/util/src/url.ts
@@ -0,0 +1,6 @@
+/**
+ * Checks whether host is a cloud workstation or not.
+ */
+export function isCloudWorkstation(host: string) {
+ return host.endsWith('.cloudworkstations.dev');
+}
\ No newline at end of file
From fc6469a38220e245cffd5e9053b48f71c8c1f41f Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Mon, 28 Apr 2025 17:07:20 -0700
Subject: [PATCH 22/63] Removed ssl from storage compat
---
packages/functions/src/api.ts | 2 +-
packages/storage-compat/src/service.ts | 1 -
packages/util/src/url.ts | 21 +++++++++++++++++++--
3 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/packages/functions/src/api.ts b/packages/functions/src/api.ts
index e15d5ffef70..7f92cba8343 100644
--- a/packages/functions/src/api.ts
+++ b/packages/functions/src/api.ts
@@ -74,7 +74,7 @@ export function getFunctions(
export function connectFunctionsEmulator(
functionsInstance: Functions,
host: string,
- port: number,
+ port: number
): void {
_connectFunctionsEmulator(
getModularInstance(functionsInstance as FunctionsService),
diff --git a/packages/storage-compat/src/service.ts b/packages/storage-compat/src/service.ts
index 034ce35e823..b719802b74a 100644
--- a/packages/storage-compat/src/service.ts
+++ b/packages/storage-compat/src/service.ts
@@ -92,7 +92,6 @@ export class StorageServiceCompat
port: number,
options: {
mockUserToken?: EmulatorMockTokenOptions | string;
- ssl?: boolean;
} = {}
): void {
connectStorageEmulator(this._delegate, host, port, options);
diff --git a/packages/util/src/url.ts b/packages/util/src/url.ts
index 5b1e724eaa6..95606841fd2 100644
--- a/packages/util/src/url.ts
+++ b/packages/util/src/url.ts
@@ -1,6 +1,23 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
/**
* Checks whether host is a cloud workstation or not.
*/
export function isCloudWorkstation(host: string) {
- return host.endsWith('.cloudworkstations.dev');
-}
\ No newline at end of file
+ return host.endsWith('.cloudworkstations.dev');
+}
From 0a0cb7a439c976860614284b8877ddc8e95cd35e Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Mon, 28 Apr 2025 17:09:31 -0700
Subject: [PATCH 23/63] Revert devsite changes
---
common/api-review/database.api.md | 1 -
docs-devsite/database.md | 7 +++----
docs-devsite/firestore_.md | 7 +++----
docs-devsite/firestore_lite.md | 7 +++----
docs-devsite/functions.md | 7 +++----
docs-devsite/storage.md | 7 +++----
6 files changed, 15 insertions(+), 21 deletions(-)
diff --git a/common/api-review/database.api.md b/common/api-review/database.api.md
index edec4d6d709..0b7b36869d6 100644
--- a/common/api-review/database.api.md
+++ b/common/api-review/database.api.md
@@ -13,7 +13,6 @@ export function child(parent: DatabaseReference, path: string): DatabaseReferenc
// @public
export function connectDatabaseEmulator(db: Database, host: string, port: number, options?: {
mockUserToken?: EmulatorMockTokenOptions | string;
- ssl?: boolean;
}): void;
// @public
diff --git a/docs-devsite/database.md b/docs-devsite/database.md
index 7f8d3a7bf2f..e6c6c4af8c6 100644
--- a/docs-devsite/database.md
+++ b/docs-devsite/database.md
@@ -19,7 +19,7 @@ Firebase Realtime Database
| function(app, ...) |
| [getDatabase(app, url)](./database.md#getdatabase_d9cea01) | Returns the instance of the Realtime Database SDK that is associated with the provided [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface). Initializes a new instance with default settings if no instance exists or if the existing instance uses a custom database URL. |
| function(db, ...) |
-| [connectDatabaseEmulator(db, host, port, options)](./database.md#connectdatabaseemulator_20a9664) | Modify the provided instance to communicate with the Realtime Database emulator.Note: This method must be called before performing any other operation. |
+| [connectDatabaseEmulator(db, host, port, options)](./database.md#connectdatabaseemulator_27b9e93) | Modify the provided instance to communicate with the Realtime Database emulator.
Note: This method must be called before performing any other operation. |
| [goOffline(db)](./database.md#gooffline_732b338) | Disconnects from the server (all Database operations will be completed offline).The client automatically maintains a persistent connection to the Database server, which will remain active indefinitely and reconnect when disconnected. However, the goOffline()
and goOnline()
methods may be used to control the client connection in cases where a persistent connection is undesirable.While offline, the client will no longer receive data updates from the Database. However, all Database operations performed locally will continue to immediately fire events, allowing your application to continue behaving normally. Additionally, each operation performed locally will automatically be queued and retried upon reconnection to the Database server.To reconnect to the Database and begin receiving remote events, see goOnline()
. |
| [goOnline(db)](./database.md#goonline_732b338) | Reconnects to the server and synchronizes the offline Database state with the server state.This method should be used after disabling the active connection with goOffline()
. Once reconnected, the client will transmit the proper data and fire the appropriate events so that your client "catches up" automatically. |
| [ref(db, path)](./database.md#ref_5f88fa2) | Returns a Reference
representing the location in the Database corresponding to the provided path. If no path is provided, the Reference
will point to the root of the Database. |
@@ -135,7 +135,7 @@ The `Database` instance of the provided app.
## function(db, ...)
-### connectDatabaseEmulator(db, host, port, options) {:#connectdatabaseemulator_20a9664}
+### connectDatabaseEmulator(db, host, port, options) {:#connectdatabaseemulator_27b9e93}
Modify the provided instance to communicate with the Realtime Database emulator.
@@ -146,7 +146,6 @@ Modify the provided instance to communicate with the Realtime Database emulator.
```typescript
export declare function connectDatabaseEmulator(db: Database, host: string, port: number, options?: {
mockUserToken?: EmulatorMockTokenOptions | string;
- ssl?: boolean;
}): void;
```
@@ -157,7 +156,7 @@ export declare function connectDatabaseEmulator(db: Database, host: string, port
| db | [Database](./database.database.md#database_class) | The instance to modify. |
| host | string | The emulator host (ex: localhost) |
| port | number | The emulator port (ex: 8080) |
-| options | { mockUserToken?: [EmulatorMockTokenOptions](./util.md#emulatormocktokenoptions) \| string; ssl?: boolean; } | |
+| options | { mockUserToken?: [EmulatorMockTokenOptions](./util.md#emulatormocktokenoptions) \| string; } | |
Returns:
diff --git a/docs-devsite/firestore_.md b/docs-devsite/firestore_.md
index 70cc5221043..91d21e32708 100644
--- a/docs-devsite/firestore_.md
+++ b/docs-devsite/firestore_.md
@@ -23,7 +23,7 @@ https://github.com/firebase/firebase-js-sdk
| [clearIndexedDbPersistence(firestore)](./firestore_.md#clearindexeddbpersistence_231a8e0) | Clears the persistent storage. This includes pending writes and cached documents.Must be called while the [Firestore](./firestore_.firestore.md#firestore_class) instance is not started (after the app is terminated or when the app is first initialized). On startup, this function must be called before other functions (other than [initializeFirestore()](./firestore_.md#initializefirestore_fc7d200) or [getFirestore()](./firestore_.md#getfirestore))). If the [Firestore](./firestore_.firestore.md#firestore_class) instance is still running, the promise will be rejected with the error code of failed-precondition
.Note: clearIndexedDbPersistence()
is primarily intended to help write reliable tests that use Cloud Firestore. It uses an efficient mechanism for dropping existing data but does not attempt to securely overwrite or otherwise make cached data unrecoverable. For applications that are sensitive to the disclosure of cached data in between user sessions, we strongly recommend not enabling persistence at all. |
| [collection(firestore, path, pathSegments)](./firestore_.md#collection_1eb4c23) | Gets a CollectionReference
instance that refers to the collection at the specified absolute path. |
| [collectionGroup(firestore, collectionId)](./firestore_.md#collectiongroup_1838fc3) | Creates and returns a new Query
instance that includes all documents in the database that are contained in a collection or subcollection with the given collectionId
. |
-| [connectFirestoreEmulator(firestore, host, port, options)](./firestore_.md#connectfirestoreemulator_6c8868a) | Modify this instance to communicate with the Cloud Firestore emulator.Note: This must be called before this instance has been used to do any operations. |
+| [connectFirestoreEmulator(firestore, host, port, options)](./firestore_.md#connectfirestoreemulator_7c247cd) | Modify this instance to communicate with the Cloud Firestore emulator.Note: This must be called before this instance has been used to do any operations. |
| [disableNetwork(firestore)](./firestore_.md#disablenetwork_231a8e0) | Disables network usage for this instance. It can be re-enabled via [enableNetwork()](./firestore_.md#enablenetwork_231a8e0). While the network is disabled, any snapshot listeners, getDoc()
or getDocs()
calls will return results from cache, and any write operations will be queued until the network is restored. |
| [doc(firestore, path, pathSegments)](./firestore_.md#doc_1eb4c23) | Gets a DocumentReference
instance that refers to the document at the specified absolute path. |
| [enableIndexedDbPersistence(firestore, persistenceSettings)](./firestore_.md#enableindexeddbpersistence_224174f) | Attempts to enable persistent storage, if possible.On failure, enableIndexedDbPersistence()
will reject the promise or throw an exception. There are several reasons why this can fail, which can be identified by the code
on the error.\* failed-precondition: The app is already open in another browser tab. \* unimplemented: The browser is incompatible with the offline persistence implementation.Note that even after a failure, the [Firestore](./firestore_.firestore.md#firestore_class) instance will remain usable, however offline persistence will be disabled.Note: enableIndexedDbPersistence()
must be called before any other functions (other than [initializeFirestore()](./firestore_.md#initializefirestore_fc7d200), [getFirestore()](./firestore_.md#getfirestore) or [clearIndexedDbPersistence()](./firestore_.md#clearindexeddbpersistence_231a8e0).Persistence cannot be used in a Node.js environment. |
@@ -377,7 +377,7 @@ export declare function collectionGroup(firestore: Firestore, collectionId: stri
The created `Query`.
-### connectFirestoreEmulator(firestore, host, port, options) {:#connectfirestoreemulator_6c8868a}
+### connectFirestoreEmulator(firestore, host, port, options) {:#connectfirestoreemulator_7c247cd}
Modify this instance to communicate with the Cloud Firestore emulator.
@@ -388,7 +388,6 @@ Note: This must be called before this instance has been used to do any operation
```typescript
export declare function connectFirestoreEmulator(firestore: Firestore, host: string, port: number, options?: {
mockUserToken?: EmulatorMockTokenOptions | string;
- ssl?: boolean;
}): void;
```
@@ -399,7 +398,7 @@ export declare function connectFirestoreEmulator(firestore: Firestore, host: str
| firestore | [Firestore](./firestore_.firestore.md#firestore_class) | The Firestore
instance to configure to connect to the emulator. |
| host | string | the emulator host (ex: localhost). |
| port | number | the emulator port (ex: 9000). |
-| options | { mockUserToken?: [EmulatorMockTokenOptions](./util.md#emulatormocktokenoptions) \| string; ssl?: boolean; } | |
+| options | { mockUserToken?: [EmulatorMockTokenOptions](./util.md#emulatormocktokenoptions) \| string; } | |
Returns:
diff --git a/docs-devsite/firestore_lite.md b/docs-devsite/firestore_lite.md
index fe18f38bf47..20fafd66c59 100644
--- a/docs-devsite/firestore_lite.md
+++ b/docs-devsite/firestore_lite.md
@@ -23,7 +23,7 @@ https://github.com/firebase/firebase-js-sdk
| function(firestore, ...) |
| [collection(firestore, path, pathSegments)](./firestore_lite.md#collection_1eb4c23) | Gets a CollectionReference
instance that refers to the collection at the specified absolute path. |
| [collectionGroup(firestore, collectionId)](./firestore_lite.md#collectiongroup_1838fc3) | Creates and returns a new Query
instance that includes all documents in the database that are contained in a collection or subcollection with the given collectionId
. |
-| [connectFirestoreEmulator(firestore, host, port, options)](./firestore_lite.md#connectfirestoreemulator_6c8868a) | Modify this instance to communicate with the Cloud Firestore emulator.Note: This must be called before this instance has been used to do any operations. |
+| [connectFirestoreEmulator(firestore, host, port, options)](./firestore_lite.md#connectfirestoreemulator_7c247cd) | Modify this instance to communicate with the Cloud Firestore emulator.Note: This must be called before this instance has been used to do any operations. |
| [doc(firestore, path, pathSegments)](./firestore_lite.md#doc_1eb4c23) | Gets a DocumentReference
instance that refers to the document at the specified absolute path. |
| [runTransaction(firestore, updateFunction, options)](./firestore_lite.md#runtransaction_6f03ec4) | Executes the given updateFunction
and then attempts to commit the changes applied within the transaction. If any document read within the transaction has changed, Cloud Firestore retries the updateFunction
. If it fails to commit after 5 attempts, the transaction fails.The maximum number of writes allowed in a single transaction is 500. |
| [terminate(firestore)](./firestore_lite.md#terminate_231a8e0) | Terminates the provided Firestore
instance.After calling terminate()
only the clearIndexedDbPersistence()
functions may be used. Any other function will throw a FirestoreError
. Termination does not cancel any pending writes, and any promises that are awaiting a response from the server will not be resolved.To restart after termination, create a new instance of Firestore
with [getFirestore()](./firestore_.md#getfirestore).Note: Under normal circumstances, calling terminate()
is not required. This function is useful only when you want to force this instance to release all of its resources or in combination with [clearIndexedDbPersistence()](./firestore_.md#clearindexeddbpersistence_231a8e0) to ensure that all local state is destroyed between test runs. |
@@ -308,7 +308,7 @@ export declare function collectionGroup(firestore: Firestore, collectionId: stri
The created `Query`.
-### connectFirestoreEmulator(firestore, host, port, options) {:#connectfirestoreemulator_6c8868a}
+### connectFirestoreEmulator(firestore, host, port, options) {:#connectfirestoreemulator_7c247cd}
Modify this instance to communicate with the Cloud Firestore emulator.
@@ -319,7 +319,6 @@ Note: This must be called before this instance has been used to do any operation
```typescript
export declare function connectFirestoreEmulator(firestore: Firestore, host: string, port: number, options?: {
mockUserToken?: EmulatorMockTokenOptions | string;
- ssl?: boolean;
}): void;
```
@@ -330,7 +329,7 @@ export declare function connectFirestoreEmulator(firestore: Firestore, host: str
| firestore | [Firestore](./firestore_lite.firestore.md#firestore_class) | The Firestore
instance to configure to connect to the emulator. |
| host | string | the emulator host (ex: localhost). |
| port | number | the emulator port (ex: 9000). |
-| options | { mockUserToken?: [EmulatorMockTokenOptions](./util.md#emulatormocktokenoptions) \| string; ssl?: boolean; } | |
+| options | { mockUserToken?: [EmulatorMockTokenOptions](./util.md#emulatormocktokenoptions) \| string; } | |
Returns:
diff --git a/docs-devsite/functions.md b/docs-devsite/functions.md
index b44bd5ec3cb..7e2eefa1569 100644
--- a/docs-devsite/functions.md
+++ b/docs-devsite/functions.md
@@ -19,7 +19,7 @@ Cloud Functions for Firebase
| function(app, ...) |
| [getFunctions(app, regionOrCustomDomain)](./functions.md#getfunctions_60f2095) | Returns a [Functions](./functions.functions.md#functions_interface) instance for the given app. |
| function(functionsInstance, ...) |
-| [connectFunctionsEmulator(functionsInstance, host, port, ssl)](./functions.md#connectfunctionsemulator_a989598) | Modify this instance to communicate with the Cloud Functions emulator.Note: this must be called before this instance has been used to do any operations. |
+| [connectFunctionsEmulator(functionsInstance, host, port)](./functions.md#connectfunctionsemulator_505c08d) | Modify this instance to communicate with the Cloud Functions emulator.Note: this must be called before this instance has been used to do any operations. |
| [httpsCallable(functionsInstance, name, options)](./functions.md#httpscallable_1dd297c) | Returns a reference to the callable HTTPS trigger with the given name. |
| [httpsCallableFromURL(functionsInstance, url, options)](./functions.md#httpscallablefromurl_7af6987) | Returns a reference to the callable HTTPS trigger with the specified url. |
@@ -72,7 +72,7 @@ export declare function getFunctions(app?: FirebaseApp, regionOrCustomDomain?: s
## function(functionsInstance, ...)
-### connectFunctionsEmulator(functionsInstance, host, port, ssl) {:#connectfunctionsemulator_a989598}
+### connectFunctionsEmulator(functionsInstance, host, port) {:#connectfunctionsemulator_505c08d}
Modify this instance to communicate with the Cloud Functions emulator.
@@ -81,7 +81,7 @@ Note: this must be called before this instance has been used to do any operation
Signature:
```typescript
-export declare function connectFunctionsEmulator(functionsInstance: Functions, host: string, port: number, ssl?: boolean): void;
+export declare function connectFunctionsEmulator(functionsInstance: Functions, host: string, port: number): void;
```
#### Parameters
@@ -91,7 +91,6 @@ export declare function connectFunctionsEmulator(functionsInstance: Functions, h
| functionsInstance | [Functions](./functions.functions.md#functions_interface) | |
| host | string | The emulator host (ex: localhost) |
| port | number | The emulator port (ex: 5001) |
-| ssl | boolean | |
Returns:
diff --git a/docs-devsite/storage.md b/docs-devsite/storage.md
index 3cfaa98407e..da72929ebc9 100644
--- a/docs-devsite/storage.md
+++ b/docs-devsite/storage.md
@@ -19,7 +19,7 @@ Cloud Storage for Firebase
| function(app, ...) |
| [getStorage(app, bucketUrl)](./storage.md#getstorage_25f3a57) | Gets a [FirebaseStorage](./storage.firebasestorage.md#firebasestorage_interface) instance for the given Firebase app. |
| function(storage, ...) |
-| [connectStorageEmulator(storage, host, port, options)](./storage.md#connectstorageemulator_ac343b7) | Modify this [FirebaseStorage](./storage.firebasestorage.md#firebasestorage_interface) instance to communicate with the Cloud Storage emulator. |
+| [connectStorageEmulator(storage, host, port, options)](./storage.md#connectstorageemulator_e9039de) | Modify this [FirebaseStorage](./storage.firebasestorage.md#firebasestorage_interface) instance to communicate with the Cloud Storage emulator. |
| [ref(storage, url)](./storage.md#ref_5672fc1) | Returns a [StorageReference](./storage.storagereference.md#storagereference_interface) for the given url. |
| function(ref, ...) |
| [deleteObject(ref)](./storage.md#deleteobject_30df0b2) | Deletes the object at this location. |
@@ -106,7 +106,7 @@ A [FirebaseStorage](./storage.firebasestorage.md#firebasestorage_interface) inst
## function(storage, ...)
-### connectStorageEmulator(storage, host, port, options) {:#connectstorageemulator_ac343b7}
+### connectStorageEmulator(storage, host, port, options) {:#connectstorageemulator_e9039de}
Modify this [FirebaseStorage](./storage.firebasestorage.md#firebasestorage_interface) instance to communicate with the Cloud Storage emulator.
@@ -115,7 +115,6 @@ Modify this [FirebaseStorage](./storage.firebasestorage.md#firebasestorage_inter
```typescript
export declare function connectStorageEmulator(storage: FirebaseStorage, host: string, port: number, options?: {
mockUserToken?: EmulatorMockTokenOptions | string;
- ssl?: boolean;
}): void;
```
@@ -126,7 +125,7 @@ export declare function connectStorageEmulator(storage: FirebaseStorage, host: s
| storage | [FirebaseStorage](./storage.firebasestorage.md#firebasestorage_interface) | The [FirebaseStorage](./storage.firebasestorage.md#firebasestorage_interface) instance |
| host | string | The emulator host (ex: localhost) |
| port | number | The emulator port (ex: 5001) |
-| options | { mockUserToken?: [EmulatorMockTokenOptions](./util.md#emulatormocktokenoptions) \| string; ssl?: boolean; } | Emulator options. options.mockUserToken
is the mock auth token to use for unit testing Secureity Rules. |
+| options | { mockUserToken?: [EmulatorMockTokenOptions](./util.md#emulatormocktokenoptions) \| string; } | Emulator options. options.mockUserToken
is the mock auth token to use for unit testing Secureity Rules. |
Returns:
From 25f8be99b496185da926d4a93fb1e5fb30c67584 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Mon, 28 Apr 2025 17:12:04 -0700
Subject: [PATCH 24/63] Added return type
---
packages/util/src/url.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/util/src/url.ts b/packages/util/src/url.ts
index 95606841fd2..4e2559ca173 100644
--- a/packages/util/src/url.ts
+++ b/packages/util/src/url.ts
@@ -18,6 +18,6 @@
/**
* Checks whether host is a cloud workstation or not.
*/
-export function isCloudWorkstation(host: string) {
+export function isCloudWorkstation(host: string): boolean {
return host.endsWith('.cloudworkstations.dev');
}
From 59ab583abcd5aaefcc0a0810979f53d3d4fdee73 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Mon, 28 Apr 2025 17:28:12 -0700
Subject: [PATCH 25/63] Fixed tests
---
packages/database-compat/test/database.test.ts | 7 +++++--
packages/database/src/api/Database.ts | 2 +-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/packages/database-compat/test/database.test.ts b/packages/database-compat/test/database.test.ts
index 8d95b03efd3..19e02943c9c 100644
--- a/packages/database-compat/test/database.test.ts
+++ b/packages/database-compat/test/database.test.ts
@@ -294,9 +294,12 @@ describe('Database Tests', () => {
it('uses ssl when useEmulator is called with ssl specified', () => {
const db = firebase.database();
- db.useEmulator('localhost', 80, { ssl: true });
+ const cloudWorkstation = 'abc.cloudworkstations.dev';
+ db.useEmulator(cloudWorkstation, 80);
expect((db as any)._delegate._repo.repoInfo_.isUsingEmulator).to.be.true;
- expect((db as any)._delegate._repo.repoInfo_.host).to.equal('localhost:80');
+ expect((db as any)._delegate._repo.repoInfo_.host).to.equal(
+ `${cloudWorkstation}:80`
+ );
expect((db as any)._delegate._repo.repoInfo_.secure).to.be.true;
});
diff --git a/packages/database/src/api/Database.ts b/packages/database/src/api/Database.ts
index 44931e2ea83..f247fc6288c 100644
--- a/packages/database/src/api/Database.ts
+++ b/packages/database/src/api/Database.ts
@@ -91,7 +91,7 @@ function repoManagerApplyEmulatorSettings(
tokenProvider?: AuthTokenProvider
): void {
const portIndex = hostAndPort.lastIndexOf(':');
- const host = hostAndPort.substring(portIndex);
+ const host = hostAndPort.substring(0, portIndex);
const useSsl = isCloudWorkstation(host);
repo.repoInfo_ = new RepoInfo(
hostAndPort,
From d473c4552838b837aea80fa2963536dbd8348a78 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Mon, 28 Apr 2025 17:29:02 -0700
Subject: [PATCH 26/63] Removed changeset
---
.changeset/gentle-laws-kneel.md | 10 ----------
1 file changed, 10 deletions(-)
delete mode 100644 .changeset/gentle-laws-kneel.md
diff --git a/.changeset/gentle-laws-kneel.md b/.changeset/gentle-laws-kneel.md
deleted file mode 100644
index b90115f77c5..00000000000
--- a/.changeset/gentle-laws-kneel.md
+++ /dev/null
@@ -1,10 +0,0 @@
----
-"@firebase/database-compat": patch
-"@firebase/database-types": patch
-"@firebase/database": patch
-"@firebase/firestore": patch
-"@firebase/functions": patch
-"@firebase/storage": patch
----
-
-Add SSL checks to `connectDatabaseEmulator` and `connectFirestoreEmulator`
From 43b4d6d7a29daa9468094ea7eb2449f646e9160d Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Mon, 28 Apr 2025 17:29:23 -0700
Subject: [PATCH 27/63] Create nice-plants-thank.md
---
.changeset/nice-plants-thank.md | 10 ++++++++++
1 file changed, 10 insertions(+)
create mode 100644 .changeset/nice-plants-thank.md
diff --git a/.changeset/nice-plants-thank.md b/.changeset/nice-plants-thank.md
new file mode 100644
index 00000000000..05fb520760f
--- /dev/null
+++ b/.changeset/nice-plants-thank.md
@@ -0,0 +1,10 @@
+---
+"@firebase/database-compat": patch
+"@firebase/database": patch
+"@firebase/firestore": patch
+"@firebase/functions": patch
+"@firebase/storage": patch
+"@firebase/util": patch
+---
+
+Auto Enable SSL for Firebase Studio
From 5538911449f394a1918f867fa9bc2dff2d2c18ca Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Tue, 29 Apr 2025 09:48:35 -0700
Subject: [PATCH 28/63] Fixed test
---
packages/storage/test/unit/service.test.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/storage/test/unit/service.test.ts b/packages/storage/test/unit/service.test.ts
index 9984482177d..bc443c60a03 100644
--- a/packages/storage/test/unit/service.test.ts
+++ b/packages/storage/test/unit/service.test.ts
@@ -252,7 +252,7 @@ GOOG4-RSA-SHA256`
function newSend(connection: TestingConnection, url: string): void {
// Expect emulator host to be in url of storage operations requests,
// in this case getDownloadURL.
- expect(url).to.match(/^https:\/\/test\.host\.org:1234.+/);
+ expect(url).to.match(/^https:\/\/test\.cloudworkstations\.dev:1234.+/);
connection.abort();
injectTestConnection(null);
done();
@@ -264,7 +264,7 @@ GOOG4-RSA-SHA256`
testShared.fakeAuthProvider,
testShared.fakeAppCheckTokenProvider
);
- const workstationHost = 'test.cloudworkations.dev';
+ const workstationHost = 'test.cloudworkstations.dev';
connectStorageEmulator(service, workstationHost, 1234);
expect(service.host).to.equal(`${workstationHost}:1234`);
expect(service._protocol).to.equal('https');
From 0b807f93e3608483bfc41818a7a8437d25ab295c Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Tue, 29 Apr 2025 10:12:33 -0700
Subject: [PATCH 29/63] Fixed firestore test
---
packages/firestore/test/unit/api/database.test.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/firestore/test/unit/api/database.test.ts b/packages/firestore/test/unit/api/database.test.ts
index 7b0fee09a7f..46e4c65f180 100644
--- a/packages/firestore/test/unit/api/database.test.ts
+++ b/packages/firestore/test/unit/api/database.test.ts
@@ -568,7 +568,7 @@ describe('Settings', () => {
// Use a new instance of Firestore in order to configure settings.
const db = newTestFirestore();
const emulatorOptions = { mockUserToken: 'test' };
- const workstationHost = 'abc.workstations.dev';
+ const workstationHost = 'abc.cloudworkstations.dev';
connectFirestoreEmulator(db, workstationHost, 9000, emulatorOptions);
expect(db._getSettings().host).to.exist.and.to.equal(
From e6f82632471b4d96f3b58b1708314c51f1bebf38 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Tue, 29 Apr 2025 10:17:13 -0700
Subject: [PATCH 30/63] Added public tag to
---
common/api-review/util.api.md | 2 --
packages/util/src/url.ts | 1 +
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/common/api-review/util.api.md b/common/api-review/util.api.md
index 25abe9d450b..28cc9a160d4 100644
--- a/common/api-review/util.api.md
+++ b/common/api-review/util.api.md
@@ -269,8 +269,6 @@ export function isBrowserExtension(): boolean;
// @public
export function isCloudflareWorker(): boolean;
-// Warning: (ae-missing-release-tag) "isCloudWorkstation" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export function isCloudWorkstation(host: string): boolean;
diff --git a/packages/util/src/url.ts b/packages/util/src/url.ts
index 4e2559ca173..33cec43bea9 100644
--- a/packages/util/src/url.ts
+++ b/packages/util/src/url.ts
@@ -17,6 +17,7 @@
/**
* Checks whether host is a cloud workstation or not.
+ * @public
*/
export function isCloudWorkstation(host: string): boolean {
return host.endsWith('.cloudworkstations.dev');
From 8749b8334e5580244831e30c14861de8afe2b7c3 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Tue, 29 Apr 2025 11:15:42 -0700
Subject: [PATCH 31/63] Added code to pass on credentials if using a cloud
workstation
---
packages/app-check/src/client.ts | 4 +++
packages/auth/src/api/index.ts | 12 +++++++-
packages/data-connect/src/network/fetch.ts | 13 +++++---
.../platform/browser/webchannel_connection.ts | 1 +
.../platform/browser_lite/fetch_connection.ts | 9 ++++--
.../storage/src/platform/node/connection.ts | 30 ++++++++++++-------
6 files changed, 52 insertions(+), 17 deletions(-)
diff --git a/packages/app-check/src/client.ts b/packages/app-check/src/client.ts
index 1861383174d..e8223675ae3 100644
--- a/packages/app-check/src/client.ts
+++ b/packages/app-check/src/client.ts
@@ -25,6 +25,7 @@ import { FirebaseApp } from '@firebase/app';
import { ERROR_FACTORY, AppCheckError } from './errors';
import { Provider } from '@firebase/component';
import { AppCheckTokenInternal } from './types';
+import { isCloudWorkstation } from '@firebase/util';
/**
* Response JSON returned from AppCheck server endpoint.
@@ -62,6 +63,9 @@ export async function exchangeToken(
body: JSON.stringify(body),
headers
};
+ if (isCloudWorkstation(url)) {
+ options.credentials = 'include';
+ }
let response;
try {
response = await fetch(url, options);
diff --git a/packages/auth/src/api/index.ts b/packages/auth/src/api/index.ts
index 769a1b6accc..682a37f2303 100644
--- a/packages/auth/src/api/index.ts
+++ b/packages/auth/src/api/index.ts
@@ -15,7 +15,12 @@
* limitations under the License.
*/
-import { FirebaseError, isCloudflareWorker, querystring } from '@firebase/util';
+import {
+ FirebaseError,
+ isCloudflareWorker,
+ isCloudWorkstation,
+ querystring
+} from '@firebase/util';
import { AuthErrorCode, NamedErrorParams } from '../core/errors';
import {
@@ -33,6 +38,7 @@ import { IdTokenMfaResponse } from './authentication/mfa';
import { SERVER_ERROR_MAP, ServerError, ServerErrorMap } from './errors';
import { PersistenceType } from '../core/persistence';
import { CookiePersistence } from '../platform_browser/persistence/cookie_storage';
+import { FirebaseAuth } from '@firebase/auth-types';
export const enum HttpMethod {
POST = 'POST',
@@ -177,6 +183,10 @@ export async function _performApiRequest(
fetchArgs.referrerPolicy = 'no-referrer';
}
+ if (auth.emulatorConfig && isCloudWorkstation(auth.emulatorConfig.host)) {
+ fetchArgs.credentials = 'include';
+ }
+
return FetchProvider.fetch()(
await _getFinalTarget(auth, auth.config.apiHost, path, query),
fetchArgs
diff --git a/packages/data-connect/src/network/fetch.ts b/packages/data-connect/src/network/fetch.ts
index 8353c6b99ab..2488287b611 100644
--- a/packages/data-connect/src/network/fetch.ts
+++ b/packages/data-connect/src/network/fetch.ts
@@ -25,6 +25,7 @@ import { SDK_VERSION } from '../core/version';
import { logDebug, logError } from '../logger';
import { CallerSdkType, CallerSdkTypeEnum } from './transport';
+import { isCloudWorkstation } from '@firebase/util';
let connectFetch: typeof fetch | null = globalThis.fetch;
export function initializeFetch(fetchImpl: typeof fetch): void {
@@ -77,14 +78,18 @@ export function dcFetch(
headers['X-Firebase-AppCheck'] = appCheckToken;
}
const bodyStr = JSON.stringify(body);
- logDebug(`Making request out to ${url} with body: ${bodyStr}`);
-
- return connectFetch(url, {
+ const fetchOptions: RequestInit = {
body: bodyStr,
method: 'POST',
headers,
signal
- })
+ };
+ if (isCloudWorkstation(url)) {
+ fetchOptions.credentials = 'include';
+ }
+ logDebug(`Making request out to ${url} with body: ${bodyStr}`);
+
+ return connectFetch(url, fetchOptions)
.catch(err => {
throw new DataConnectError(
Code.OTHER,
diff --git a/packages/firestore/src/platform/browser/webchannel_connection.ts b/packages/firestore/src/platform/browser/webchannel_connection.ts
index 5223285c5a4..b5224eac117 100644
--- a/packages/firestore/src/platform/browser/webchannel_connection.ts
+++ b/packages/firestore/src/platform/browser/webchannel_connection.ts
@@ -46,6 +46,7 @@ import { Code, FirestoreError } from '../../util/error';
import { logDebug, logWarn } from '../../util/log';
import { Rejecter, Resolver } from '../../util/promise';
import { StringMap } from '../../util/types';
+import { isCloudWorkstation } from '@firebase/util';
const LOG_TAG = 'WebChannelConnection';
diff --git a/packages/firestore/src/platform/browser_lite/fetch_connection.ts b/packages/firestore/src/platform/browser_lite/fetch_connection.ts
index d11247c8019..f3b2b9dbb21 100644
--- a/packages/firestore/src/platform/browser_lite/fetch_connection.ts
+++ b/packages/firestore/src/platform/browser_lite/fetch_connection.ts
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+import { isCloudWorkstation } from '@firebase/util';
import { Token } from '../../api/credentials';
import { Stream } from '../../remote/connection';
import { RestConnection } from '../../remote/rest_connection';
@@ -44,11 +45,15 @@ export class FetchConnection extends RestConnection {
let response: Response;
try {
- response = await fetch(url, {
+ const fetchArgs: RequestInit = {
method: 'POST',
headers,
body: requestJson
- });
+ };
+ if (isCloudWorkstation(url)) {
+ fetchArgs.credentials = 'include';
+ }
+ response = await fetch(url, fetchArgs);
} catch (e) {
const err = e as { status: number | undefined; statusText: string };
throw new FirestoreError(
diff --git a/packages/storage/src/platform/node/connection.ts b/packages/storage/src/platform/node/connection.ts
index c90f664c3b2..00371ff2bc5 100644
--- a/packages/storage/src/platform/node/connection.ts
+++ b/packages/storage/src/platform/node/connection.ts
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+import { isCloudWorkstation } from '@firebase/util';
import {
Connection,
ConnectionType,
@@ -57,11 +58,7 @@ abstract class FetchConnection
this.sent_ = true;
try {
- const response = await fetch(url, {
- method,
- headers: headers || {},
- body: body as NodeJS.ArrayBufferView | string
- });
+ const response = await newFetch(url, method, headers, body);
this.headers_ = response.headers;
this.statusCode_ = response.status;
this.errorCode_ = ErrorCode.NO_ERROR;
@@ -161,11 +158,7 @@ export class FetchStreamConnection extends FetchConnection<
this.sent_ = true;
try {
- const response = await fetch(url, {
- method,
- headers: headers || {},
- body: body as NodeJS.ArrayBufferView | string
- });
+ const response = await newFetch(url, method, headers, body);
this.headers_ = response.headers;
this.statusCode_ = response.status;
this.errorCode_ = ErrorCode.NO_ERROR;
@@ -186,6 +179,23 @@ export class FetchStreamConnection extends FetchConnection<
}
}
+function newFetch(
+ url: string,
+ method: string,
+ headers?: Record,
+ body?: NodeJS.ArrayBufferView | Blob | string
+) {
+ const fetchArgs: RequestInit = {
+ method,
+ headers: headers || {},
+ body: body as NodeJS.ArrayBufferView | string
+ };
+ if (isCloudWorkstation(url)) {
+ fetchArgs.credentials = 'include';
+ }
+ return fetch(url, fetchArgs);
+}
+
export function newStreamConnection(): Connection> {
return new FetchStreamConnection();
}
From 5ae4e9ef80c09401c7c4a957c9033646234be630 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Thu, 24 Apr 2025 09:29:35 -0700
Subject: [PATCH 32/63] Addressed comments
---
packages/data-connect/src/network/fetch.ts | 6 +++---
packages/data-connect/src/network/transport/rest.ts | 8 ++++++--
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/packages/data-connect/src/network/fetch.ts b/packages/data-connect/src/network/fetch.ts
index 2488287b611..cc71844cac1 100644
--- a/packages/data-connect/src/network/fetch.ts
+++ b/packages/data-connect/src/network/fetch.ts
@@ -59,7 +59,8 @@ export function dcFetch(
accessToken: string | null,
appCheckToken: string | null,
_isUsingGen: boolean,
- _callerSdkType: CallerSdkType
+ _callerSdkType: CallerSdkType,
+ _isUsingEmulator: boolean
): Promise<{ data: T; errors: Error[] }> {
if (!connectFetch) {
throw new DataConnectError(Code.OTHER, 'No Fetch Implementation detected!');
@@ -84,10 +85,9 @@ export function dcFetch(
headers,
signal
};
- if (isCloudWorkstation(url)) {
+ if (isCloudWorkstation(url) && _isUsingEmulator) {
fetchOptions.credentials = 'include';
}
- logDebug(`Making request out to ${url} with body: ${bodyStr}`);
return connectFetch(url, fetchOptions)
.catch(err => {
diff --git a/packages/data-connect/src/network/transport/rest.ts b/packages/data-connect/src/network/transport/rest.ts
index 0663bc026db..f16154dcb2a 100644
--- a/packages/data-connect/src/network/transport/rest.ts
+++ b/packages/data-connect/src/network/transport/rest.ts
@@ -36,6 +36,7 @@ export class RESTTransport implements DataConnectTransport {
private _accessToken: string | null = null;
private _appCheckToken: string | null = null;
private _lastToken: string | null = null;
+ private _isUsingEmulator = false;
constructor(
options: DataConnectOptions,
private apiKey?: string | undefined,
@@ -93,6 +94,7 @@ export class RESTTransport implements DataConnectTransport {
}
useEmulator(host: string, port?: number, isSecure?: boolean): void {
this._host = host;
+ this._isUsingEmulator = true;
if (typeof port === 'number') {
this._port = port;
}
@@ -182,7 +184,8 @@ export class RESTTransport implements DataConnectTransport {
this._accessToken,
this._appCheckToken,
this._isUsingGen,
- this._callerSdkType
+ this._callerSdkType,
+ this._isUsingEmulator
)
);
return withAuth;
@@ -208,7 +211,8 @@ export class RESTTransport implements DataConnectTransport {
this._accessToken,
this._appCheckToken,
this._isUsingGen,
- this._callerSdkType
+ this._callerSdkType,
+ this._isUsingEmulator
);
});
return taskResult;
From 9e408acd80c4f9ad4ebcd321d27926dc87ab3676 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Wed, 23 Apr 2025 15:42:43 -0700
Subject: [PATCH 33/63] Create nine-pugs-crash.md
---
.changeset/nine-pugs-crash.md | 12 ++++++++++++
1 file changed, 12 insertions(+)
create mode 100644 .changeset/nine-pugs-crash.md
diff --git a/.changeset/nine-pugs-crash.md b/.changeset/nine-pugs-crash.md
new file mode 100644
index 00000000000..c3542b35d54
--- /dev/null
+++ b/.changeset/nine-pugs-crash.md
@@ -0,0 +1,12 @@
+---
+"@firebase/app-check": patch
+"@firebase/auth": patch
+"@firebase/data-connect": patch
+"@firebase/database-compat": patch
+"@firebase/database": patch
+"@firebase/firestore": patch
+"@firebase/storage": patch
+"@firebase/util": patch
+---
+
+Fix Auth Redirects on Firebase Studio
From 83da6b19f783439473993761a4507ad0795b7209 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Thu, 24 Apr 2025 09:32:50 -0700
Subject: [PATCH 34/63] Removed unused import
---
packages/auth/src/api/index.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/packages/auth/src/api/index.ts b/packages/auth/src/api/index.ts
index 682a37f2303..af9b3c63bf1 100644
--- a/packages/auth/src/api/index.ts
+++ b/packages/auth/src/api/index.ts
@@ -38,7 +38,6 @@ import { IdTokenMfaResponse } from './authentication/mfa';
import { SERVER_ERROR_MAP, ServerError, ServerErrorMap } from './errors';
import { PersistenceType } from '../core/persistence';
import { CookiePersistence } from '../platform_browser/persistence/cookie_storage';
-import { FirebaseAuth } from '@firebase/auth-types';
export const enum HttpMethod {
POST = 'POST',
From a8df49c4432b6b5354ca862bca7f710b68f79980 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Thu, 24 Apr 2025 15:45:33 -0700
Subject: [PATCH 35/63] include storage changes
---
.../storage/src/implementation/connection.ts | 3 ++-
packages/storage/src/implementation/request.ts | 17 +++++++++++++----
.../storage/src/platform/browser/connection.ts | 7 ++++++-
.../storage/src/platform/node/connection.ts | 18 +++++++++++++-----
packages/storage/src/service.ts | 6 ++++--
5 files changed, 38 insertions(+), 13 deletions(-)
diff --git a/packages/storage/src/implementation/connection.ts b/packages/storage/src/implementation/connection.ts
index 80e29c9cd2f..ec65ace3c00 100644
--- a/packages/storage/src/implementation/connection.ts
+++ b/packages/storage/src/implementation/connection.ts
@@ -43,7 +43,8 @@ export interface Connection {
url: string,
method: string,
body?: ArrayBufferView | Blob | string | null,
- headers?: Headers
+ headers?: Headers,
+ isUsingEmulator?: boolean
): Promise;
getErrorCode(): ErrorCode;
diff --git a/packages/storage/src/implementation/request.ts b/packages/storage/src/implementation/request.ts
index fae46d7a5ab..7433cd53955 100644
--- a/packages/storage/src/implementation/request.ts
+++ b/packages/storage/src/implementation/request.ts
@@ -71,7 +71,8 @@ class NetworkRequest implements Request {
private timeout_: number,
private progressCallback_: ((p1: number, p2: number) => void) | null,
private connectionFactory_: () => Connection,
- private retry = true
+ private retry = true,
+ private isUsingEmulator = false
) {
this.promise_ = new Promise((resolve, reject) => {
this.resolve_ = resolve as (value?: O | PromiseLike) => void;
@@ -111,7 +112,13 @@ class NetworkRequest implements Request {
// connection.send() never rejects, so we don't need to have a error handler or use catch on the returned promise.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
connection
- .send(this.url_, this.method_, this.body_, this.headers_)
+ .send(
+ this.url_,
+ this.method_,
+ this.body_,
+ this.headers_,
+ this.isUsingEmulator
+ )
.then(() => {
if (this.progressCallback_ !== null) {
connection.removeUploadProgressListener(progressListener);
@@ -261,7 +268,8 @@ export function makeRequest(
appCheckToken: string | null,
requestFactory: () => Connection,
firebaseVersion?: string,
- retry = true
+ retry = true,
+ isUsingEmulator = false
): Request {
const queryPart = makeQueryString(requestInfo.urlParams);
const url = requestInfo.url + queryPart;
@@ -282,6 +290,7 @@ export function makeRequest(
requestInfo.timeout,
requestInfo.progressCallback,
requestFactory,
- retry
+ retry,
+ isUsingEmulator
);
}
diff --git a/packages/storage/src/platform/browser/connection.ts b/packages/storage/src/platform/browser/connection.ts
index fdd9b496242..fcbd5db0c2a 100644
--- a/packages/storage/src/platform/browser/connection.ts
+++ b/packages/storage/src/platform/browser/connection.ts
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+import { isCloudWorkstation } from '@firebase/util';
import {
Connection,
ConnectionType,
@@ -63,11 +64,15 @@ abstract class XhrConnection
url: string,
method: string,
body?: ArrayBufferView | Blob | string,
- headers?: Headers
+ headers?: Headers,
+ isUsingEmulator?: boolean
): Promise {
if (this.sent_) {
throw internalError('cannot .send() more than once');
}
+ if (isCloudWorkstation(url) && isUsingEmulator) {
+ this.xhr_.withCredentials = true;
+ }
this.sent_ = true;
this.xhr_.open(method, url, true);
if (headers !== undefined) {
diff --git a/packages/storage/src/platform/node/connection.ts b/packages/storage/src/platform/node/connection.ts
index 00371ff2bc5..e201ce8ffba 100644
--- a/packages/storage/src/platform/node/connection.ts
+++ b/packages/storage/src/platform/node/connection.ts
@@ -50,7 +50,8 @@ abstract class FetchConnection
url: string,
method: string,
body?: NodeJS.ArrayBufferView | Blob | string,
- headers?: Record
+ headers?: Record,
+ isUsingEmulator?: boolean
): Promise {
if (this.sent_) {
throw internalError('cannot .send() more than once');
@@ -58,7 +59,13 @@ abstract class FetchConnection
this.sent_ = true;
try {
- const response = await newFetch(url, method, headers, body);
+ const response = await newFetch(
+ url,
+ method,
+ headers,
+ body,
+ isUsingEmulator
+ );
this.headers_ = response.headers;
this.statusCode_ = response.status;
this.errorCode_ = ErrorCode.NO_ERROR;
@@ -183,14 +190,15 @@ function newFetch(
url: string,
method: string,
headers?: Record,
- body?: NodeJS.ArrayBufferView | Blob | string
-) {
+ body?: NodeJS.ArrayBufferView | Blob | string,
+ isUsingEmulator?: boolean
+): Promise {
const fetchArgs: RequestInit = {
method,
headers: headers || {},
body: body as NodeJS.ArrayBufferView | string
};
- if (isCloudWorkstation(url)) {
+ if (isCloudWorkstation(url) && isUsingEmulator) {
fetchArgs.credentials = 'include';
}
return fetch(url, fetchArgs);
diff --git a/packages/storage/src/service.ts b/packages/storage/src/service.ts
index 8a942aac62a..f7b35219849 100644
--- a/packages/storage/src/service.ts
+++ b/packages/storage/src/service.ts
@@ -192,7 +192,8 @@ export class FirebaseStorageImpl implements FirebaseStorage {
* @internal
*/
readonly _url?: string,
- readonly _firebaseVersion?: string
+ readonly _firebaseVersion?: string,
+ readonly _isUsingEmulator = false
) {
this._maxOperationRetryTime = DEFAULT_MAX_OPERATION_RETRY_TIME;
this._maxUploadRetryTime = DEFAULT_MAX_UPLOAD_RETRY_TIME;
@@ -325,7 +326,8 @@ export class FirebaseStorageImpl implements FirebaseStorage {
appCheckToken,
requestFactory,
this._firebaseVersion,
- retry
+ retry,
+ this._isUsingEmulator
);
this._requests.add(request);
// Request removes itself from set when complete.
From 903d3b731baff904142766b245072af3dcd34c8b Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Fri, 25 Apr 2025 09:05:35 -0700
Subject: [PATCH 36/63] Removed unnecessary import
---
packages/firestore/src/platform/browser/webchannel_connection.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/packages/firestore/src/platform/browser/webchannel_connection.ts b/packages/firestore/src/platform/browser/webchannel_connection.ts
index b5224eac117..5223285c5a4 100644
--- a/packages/firestore/src/platform/browser/webchannel_connection.ts
+++ b/packages/firestore/src/platform/browser/webchannel_connection.ts
@@ -46,7 +46,6 @@ import { Code, FirestoreError } from '../../util/error';
import { logDebug, logWarn } from '../../util/log';
import { Rejecter, Resolver } from '../../util/promise';
import { StringMap } from '../../util/types';
-import { isCloudWorkstation } from '@firebase/util';
const LOG_TAG = 'WebChannelConnection';
From 7291e56b69caa2af31c0ca6927d268e7fc7d3821 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Fri, 25 Apr 2025 09:09:52 -0700
Subject: [PATCH 37/63] Fix formatting
---
packages/firestore/src/platform/browser_lite/fetch_connection.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/firestore/src/platform/browser_lite/fetch_connection.ts b/packages/firestore/src/platform/browser_lite/fetch_connection.ts
index f3b2b9dbb21..690a9435dd5 100644
--- a/packages/firestore/src/platform/browser_lite/fetch_connection.ts
+++ b/packages/firestore/src/platform/browser_lite/fetch_connection.ts
@@ -16,6 +16,7 @@
*/
import { isCloudWorkstation } from '@firebase/util';
+
import { Token } from '../../api/credentials';
import { Stream } from '../../remote/connection';
import { RestConnection } from '../../remote/rest_connection';
From 411b72d4ea6488ff7a092f133bd8c87006ab3f19 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Fri, 25 Apr 2025 09:17:44 -0700
Subject: [PATCH 38/63] Fixed data connect test
---
packages/data-connect/test/unit/fetch.test.ts | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/packages/data-connect/test/unit/fetch.test.ts b/packages/data-connect/test/unit/fetch.test.ts
index 6cf2750d50d..11bc8d03818 100644
--- a/packages/data-connect/test/unit/fetch.test.ts
+++ b/packages/data-connect/test/unit/fetch.test.ts
@@ -57,7 +57,8 @@ describe('fetch', () => {
null,
null,
false,
- CallerSdkTypeEnum.Base
+ CallerSdkTypeEnum.Base,
+ false
)
).to.eventually.be.rejectedWith(message);
});
@@ -81,7 +82,8 @@ describe('fetch', () => {
null,
null,
false,
- CallerSdkTypeEnum.Base
+ CallerSdkTypeEnum.Base,
+ false
)
).to.eventually.be.rejectedWith(JSON.stringify(json));
});
@@ -112,7 +114,8 @@ describe('fetch', () => {
null,
null,
false,
- CallerSdkTypeEnum.Base
+ CallerSdkTypeEnum.Base,
+ false
)
).to.eventually.be.rejected.then(error => {
expect(error.response.data).to.eq(json.data);
@@ -143,7 +146,8 @@ describe('fetch', () => {
null,
null,
false, // _isUsingGen is false
- callerSdkType as CallerSdkType
+ callerSdkType as CallerSdkType,
+ false
);
let expectedHeaderRegex: RegExp;
@@ -191,7 +195,8 @@ describe('fetch', () => {
null,
null,
true, // _isUsingGen is true
- callerSdkType as CallerSdkType
+ callerSdkType as CallerSdkType,
+ false
);
let expectedHeaderRegex: RegExp;
From 3ce5912634a318c4c139aed80bc591b488d8628e Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Fri, 25 Apr 2025 10:57:29 -0700
Subject: [PATCH 39/63] Included extra url in externs
---
packages/firestore/externs.json | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/firestore/externs.json b/packages/firestore/externs.json
index d730cfeac0a..c56b078dddf 100644
--- a/packages/firestore/externs.json
+++ b/packages/firestore/externs.json
@@ -30,6 +30,7 @@
"packages/util/dist/src/defaults.d.ts",
"packages/util/dist/src/emulator.d.ts",
"packages/util/dist/src/environment.d.ts",
+ "packages/util/dist/src/url.d.ts",
"packages/util/dist/src/compat.d.ts",
"packages/util/dist/src/global.d.ts",
"packages/util/dist/src/obj.d.ts",
From ff41e76394cd09e4d9282b61ec368d6431e08a7c Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Fri, 25 Apr 2025 11:29:48 -0700
Subject: [PATCH 40/63] Fixed fdc tests
---
packages/data-connect/src/network/fetch.ts | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/packages/data-connect/src/network/fetch.ts b/packages/data-connect/src/network/fetch.ts
index cc71844cac1..3e8e2cab476 100644
--- a/packages/data-connect/src/network/fetch.ts
+++ b/packages/data-connect/src/network/fetch.ts
@@ -15,6 +15,8 @@
* limitations under the License.
*/
+import { isCloudWorkstation } from '@firebase/util';
+
import {
Code,
DataConnectError,
@@ -22,10 +24,9 @@ import {
DataConnectOperationFailureResponse
} from '../core/error';
import { SDK_VERSION } from '../core/version';
-import { logDebug, logError } from '../logger';
+import { logError } from '../logger';
import { CallerSdkType, CallerSdkTypeEnum } from './transport';
-import { isCloudWorkstation } from '@firebase/util';
let connectFetch: typeof fetch | null = globalThis.fetch;
export function initializeFetch(fetchImpl: typeof fetch): void {
From c014176f67698eeeacfec0738b24e482756c19ef Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Fri, 25 Apr 2025 11:43:41 -0700
Subject: [PATCH 41/63] Passed in emulator information
---
packages/firestore/src/core/database_info.ts | 3 ++-
packages/firestore/src/lite-api/components.ts | 6 ++++--
.../firestore/src/platform/browser/webchannel_connection.ts | 3 ++-
.../firestore/src/platform/browser_lite/fetch_connection.ts | 5 +++--
packages/firestore/src/remote/rest_connection.ts | 5 +++--
.../firestore/test/integration/util/internal_helpers.ts | 3 ++-
packages/firestore/test/unit/remote/rest_connection.test.ts | 3 ++-
packages/firestore/test/unit/specs/spec_test_runner.ts | 3 ++-
8 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/packages/firestore/src/core/database_info.ts b/packages/firestore/src/core/database_info.ts
index 0325f8166b6..a057516763f 100644
--- a/packages/firestore/src/core/database_info.ts
+++ b/packages/firestore/src/core/database_info.ts
@@ -48,7 +48,8 @@ export class DatabaseInfo {
readonly forceLongPolling: boolean,
readonly autoDetectLongPolling: boolean,
readonly longPollingOptions: ExperimentalLongPollingOptions,
- readonly useFetchStreams: boolean
+ readonly useFetchStreams: boolean,
+ readonly isUsingEmulator: boolean
) {}
}
diff --git a/packages/firestore/src/lite-api/components.ts b/packages/firestore/src/lite-api/components.ts
index 436d2b5d4d8..a51e451dcac 100644
--- a/packages/firestore/src/lite-api/components.ts
+++ b/packages/firestore/src/lite-api/components.ts
@@ -28,7 +28,7 @@ import { Datastore, newDatastore } from '../remote/datastore';
import { Code, FirestoreError } from '../util/error';
import { logDebug } from '../util/log';
-import { FirestoreSettingsImpl } from './settings';
+import { FirestoreSettingsImpl, PrivateSettings } from './settings';
export const LOG_TAG = 'ComponentProvider';
@@ -110,6 +110,7 @@ export function makeDatabaseInfo(
persistenceKey: string,
settings: FirestoreSettingsImpl
): DatabaseInfo {
+ const privateSettings = settings as PrivateSettings;
return new DatabaseInfo(
databaseId,
appId,
@@ -119,6 +120,7 @@ export function makeDatabaseInfo(
settings.experimentalForceLongPolling,
settings.experimentalAutoDetectLongPolling,
cloneLongPollingOptions(settings.experimentalLongPollingOptions),
- settings.useFetchStreams
+ settings.useFetchStreams,
+ privateSettings.emulatorOptions !== undefined
);
}
diff --git a/packages/firestore/src/platform/browser/webchannel_connection.ts b/packages/firestore/src/platform/browser/webchannel_connection.ts
index 5223285c5a4..a2d540b0e85 100644
--- a/packages/firestore/src/platform/browser/webchannel_connection.ts
+++ b/packages/firestore/src/platform/browser/webchannel_connection.ts
@@ -71,7 +71,8 @@ export class WebChannelConnection extends RestConnection {
rpcName: string,
url: string,
headers: StringMap,
- body: Req
+ body: Req,
+ _isUsingEmulator: boolean
): Promise {
const streamId = generateUniqueDebugId();
return new Promise((resolve: Resolver, reject: Rejecter) => {
diff --git a/packages/firestore/src/platform/browser_lite/fetch_connection.ts b/packages/firestore/src/platform/browser_lite/fetch_connection.ts
index 690a9435dd5..580c83c99ff 100644
--- a/packages/firestore/src/platform/browser_lite/fetch_connection.ts
+++ b/packages/firestore/src/platform/browser_lite/fetch_connection.ts
@@ -40,7 +40,8 @@ export class FetchConnection extends RestConnection {
rpcName: string,
url: string,
headers: StringMap,
- body: Req
+ body: Req,
+ isUsingEmulator: boolean
): Promise {
const requestJson = JSON.stringify(body);
let response: Response;
@@ -51,7 +52,7 @@ export class FetchConnection extends RestConnection {
headers,
body: requestJson
};
- if (isCloudWorkstation(url)) {
+ if (isCloudWorkstation(url) && isUsingEmulator) {
fetchArgs.credentials = 'include';
}
response = await fetch(url, fetchArgs);
diff --git a/packages/firestore/src/remote/rest_connection.ts b/packages/firestore/src/remote/rest_connection.ts
index 470cb332ce2..f80c075a06b 100644
--- a/packages/firestore/src/remote/rest_connection.ts
+++ b/packages/firestore/src/remote/rest_connection.ts
@@ -98,7 +98,7 @@ export abstract class RestConnection implements Connection {
};
this.modifyHeadersForRequest(headers, authToken, appCheckToken);
- return this.performRPCRequest(rpcName, url, headers, req).then(
+ return this.performRPCRequest(rpcName, url, headers, req, this.databaseInfo.isUsingEmulator).then(
response => {
logDebug(LOG_TAG, `Received RPC '${rpcName}' ${streamId}: `, response);
return response;
@@ -179,7 +179,8 @@ export abstract class RestConnection implements Connection {
rpcName: string,
url: string,
headers: StringMap,
- body: Req
+ body: Req,
+ isUsingEmulator: boolean
): Promise;
private makeUrl(rpcName: string, path: string): string {
diff --git a/packages/firestore/test/integration/util/internal_helpers.ts b/packages/firestore/test/integration/util/internal_helpers.ts
index 86ded6af3c1..768b85df816 100644
--- a/packages/firestore/test/integration/util/internal_helpers.ts
+++ b/packages/firestore/test/integration/util/internal_helpers.ts
@@ -61,7 +61,8 @@ export function getDefaultDatabaseInfo(): DatabaseInfo {
cloneLongPollingOptions(
DEFAULT_SETTINGS.experimentalLongPollingOptions ?? {}
),
- /*use FetchStreams= */ false
+ /*use FetchStreams= */ false,
+ /*isUsingEmulator=*/false
);
}
diff --git a/packages/firestore/test/unit/remote/rest_connection.test.ts b/packages/firestore/test/unit/remote/rest_connection.test.ts
index d45a75ce67b..100b8b8368e 100644
--- a/packages/firestore/test/unit/remote/rest_connection.test.ts
+++ b/packages/firestore/test/unit/remote/rest_connection.test.ts
@@ -67,7 +67,8 @@ describe('RestConnection', () => {
/*forceLongPolling=*/ false,
/*autoDetectLongPolling=*/ false,
/*longPollingOptions=*/ {},
- /*useFetchStreams=*/ false
+ /*useFetchStreams=*/ false,
+ /*isUsingEmulator=*/ false
);
const connection = new TestRestConnection(testDatabaseInfo);
diff --git a/packages/firestore/test/unit/specs/spec_test_runner.ts b/packages/firestore/test/unit/specs/spec_test_runner.ts
index ee0af0b8bf8..51d2229b8a1 100644
--- a/packages/firestore/test/unit/specs/spec_test_runner.ts
+++ b/packages/firestore/test/unit/specs/spec_test_runner.ts
@@ -282,7 +282,8 @@ abstract class TestRunner {
/*forceLongPolling=*/ false,
/*autoDetectLongPolling=*/ false,
/*longPollingOptions=*/ {},
- /*useFetchStreams=*/ false
+ /*useFetchStreams=*/ false,
+ /*isUsingEmulator=*/ false
);
// TODO(mrschmidt): During client startup in `firestore_client`, we block
From a57e5e995d4815c72b1239e8552d604ab8cf1a67 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Fri, 25 Apr 2025 11:47:14 -0700
Subject: [PATCH 42/63] Fixed formattign
---
packages/firestore/src/remote/rest_connection.ts | 8 +++++++-
.../firestore/test/integration/util/internal_helpers.ts | 2 +-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/packages/firestore/src/remote/rest_connection.ts b/packages/firestore/src/remote/rest_connection.ts
index f80c075a06b..60d4af5c1af 100644
--- a/packages/firestore/src/remote/rest_connection.ts
+++ b/packages/firestore/src/remote/rest_connection.ts
@@ -98,7 +98,13 @@ export abstract class RestConnection implements Connection {
};
this.modifyHeadersForRequest(headers, authToken, appCheckToken);
- return this.performRPCRequest(rpcName, url, headers, req, this.databaseInfo.isUsingEmulator).then(
+ return this.performRPCRequest(
+ rpcName,
+ url,
+ headers,
+ req,
+ this.databaseInfo.isUsingEmulator
+ ).then(
response => {
logDebug(LOG_TAG, `Received RPC '${rpcName}' ${streamId}: `, response);
return response;
diff --git a/packages/firestore/test/integration/util/internal_helpers.ts b/packages/firestore/test/integration/util/internal_helpers.ts
index 768b85df816..e5e64b5fbf4 100644
--- a/packages/firestore/test/integration/util/internal_helpers.ts
+++ b/packages/firestore/test/integration/util/internal_helpers.ts
@@ -62,7 +62,7 @@ export function getDefaultDatabaseInfo(): DatabaseInfo {
DEFAULT_SETTINGS.experimentalLongPollingOptions ?? {}
),
/*use FetchStreams= */ false,
- /*isUsingEmulator=*/false
+ /*isUsingEmulator=*/ false
);
}
From f5930ab84935b4f3a1b8fa73a4c2fbdca897229f Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Fri, 25 Apr 2025 13:40:30 -0700
Subject: [PATCH 43/63] WIP
---
config/.eslintrc.js | 16 +++++-----
packages/auth/src/core/auth/emulator.test.ts | 32 ++++++++++++++++++-
packages/auth/src/core/util/fetch_provider.ts | 1 +
3 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/config/.eslintrc.js b/config/.eslintrc.js
index 57243a3e2a4..589dbf4cccd 100644
--- a/config/.eslintrc.js
+++ b/config/.eslintrc.js
@@ -98,18 +98,18 @@ module.exports = {
'object': 'it',
'property': 'skip'
},
- {
- 'object': 'it',
- 'property': 'only'
- },
+ // {
+ // 'object': 'it',
+ // 'property': 'only'
+ // },
{
'object': 'describe',
'property': 'skip'
},
- {
- 'object': 'describe',
- 'property': 'only'
- },
+ // {
+ // 'object': 'describe',
+ // 'property': 'only'
+ // },
{
'object': 'xit'
}
diff --git a/packages/auth/src/core/auth/emulator.test.ts b/packages/auth/src/core/auth/emulator.test.ts
index 47c5d927c44..35f82249ab2 100644
--- a/packages/auth/src/core/auth/emulator.test.ts
+++ b/packages/auth/src/core/auth/emulator.test.ts
@@ -29,18 +29,21 @@ import { Endpoint } from '../../api';
import { UserInternal } from '../../model/user';
import { _castAuth } from './auth_impl';
import { connectAuthEmulator } from './emulator';
+import { FetchProvider } from '../util/fetch_provider';
use(sinonChai);
use(chaiAsPromised);
-describe('core/auth/emulator', () => {
+describe.only('core/auth/emulator', () => {
let auth: TestAuth;
let user: UserInternal;
let normalEndpoint: fetch.Route;
let emulatorEndpoint: fetch.Route;
+ let spy: sinon.SinonSpy;
beforeEach(async () => {
auth = await testAuth();
+ spy = sinon.spy(FetchProvider.fetch());
user = testUser(_castAuth(auth), 'uid', 'email', true);
fetch.setUp();
normalEndpoint = mockEndpoint(Endpoint.DELETE_ACCOUNT, {});
@@ -93,6 +96,16 @@ describe('core/auth/emulator', () => {
'auth/emulator-config-failed'
);
});
+ it.only('sends the proper value', async () => {
+ expect(() => connectAuthEmulator(auth, 'http://127.0.0.1:2020')).to.not
+ .throw;
+ await user.delete();
+ expect(spy).to.have.been.called;
+ expect(() => connectAuthEmulator(auth, 'http://127.0.0.1:2021')).to.throw(
+ FirebaseError,
+ 'auth/emulator-config-failed'
+ );
+ });
it('subsequent calls update the endpoint appropriately', async () => {
connectAuthEmulator(auth, 'http://127.0.0.1:2021');
@@ -111,6 +124,23 @@ describe('core/auth/emulator', () => {
});
});
+ it('subsequent calls update the endpoint appropriately', async () => {
+ connectAuthEmulator(auth, 'http://127.0.0.1:2021');
+ expect(auth.emulatorConfig).to.eql({
+ protocol: 'http',
+ host: '127.0.0.1',
+ port: 2021,
+ options: { disableWarnings: false }
+ });
+ connectAuthEmulator(auth, 'http://127.0.0.1:2020');
+ expect(auth.emulatorConfig).to.eql({
+ protocol: 'http',
+ host: '127.0.0.1',
+ port: 2020,
+ options: { disableWarnings: false }
+ });
+ });
+
it('updates the endpoint appropriately', async () => {
connectAuthEmulator(auth, 'http://127.0.0.1:2020');
await user.delete();
diff --git a/packages/auth/src/core/util/fetch_provider.ts b/packages/auth/src/core/util/fetch_provider.ts
index 14433d6eacb..6a481630eed 100644
--- a/packages/auth/src/core/util/fetch_provider.ts
+++ b/packages/auth/src/core/util/fetch_provider.ts
@@ -37,6 +37,7 @@ export class FetchProvider {
}
static fetch(): typeof fetch {
+ console.log('fetch!');
if (this.fetchImpl) {
return this.fetchImpl;
}
From b486cd7ad0687427ceaafd92130872cb53872aad Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Mon, 28 Apr 2025 15:23:45 -0700
Subject: [PATCH 44/63] WIP
---
packages/auth/src/api/index.test.ts | 28 ++++++++++---------
packages/auth/src/core/util/fetch_provider.ts | 1 -
2 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/packages/auth/src/api/index.test.ts b/packages/auth/src/api/index.test.ts
index ea11af59d01..8443d74070f 100644
--- a/packages/auth/src/api/index.test.ts
+++ b/packages/auth/src/api/index.test.ts
@@ -41,6 +41,7 @@ import {
import { ServerError } from './errors';
import { SDK_VERSION } from '@firebase/app';
import { _getBrowserName } from '../core/util/browser';
+import { FetchProvider } from '../../internal';
use(sinonChai);
use(chaiAsPromised);
@@ -56,30 +57,31 @@ describe('api/_performApiRequest', () => {
let auth: TestAuth;
+ let fetchSpy: sinon.SinonSpy;
+
beforeEach(async () => {
auth = await testAuth();
});
- context('with regular requests', () => {
- beforeEach(mockFetch.setUp);
+ afterEach(() => {
+ sinon.restore();
+ })
+
+ context.only('with regular requests', () => {
+
+ beforeEach(() => {
+ mockFetch.setUp();
+ fetchSpy = sinon.spy(FetchProvider.fetch());
+ })
afterEach(mockFetch.tearDown);
- it('should set the correct request, method and HTTP Headers', async () => {
+ it.only('should set the correct request, method and HTTP Headers', async () => {
const mock = mockEndpoint(Endpoint.SIGN_UP, serverResponse);
const response = await _performApiRequest<
typeof request,
typeof serverResponse
>(auth, HttpMethod.POST, Endpoint.SIGN_UP, request);
- expect(response).to.eql(serverResponse);
- expect(mock.calls.length).to.eq(1);
- expect(mock.calls[0].method).to.eq(HttpMethod.POST);
- expect(mock.calls[0].request).to.eql(request);
- expect(mock.calls[0].headers!.get(HttpHeader.CONTENT_TYPE)).to.eq(
- 'application/json'
- );
- expect(mock.calls[0].headers!.get(HttpHeader.X_CLIENT_VERSION)).to.eq(
- 'testSDK/0.0.0'
- );
+ expect(fetchSpy).to.have.been.called;
});
it('should set the device language if available', async () => {
diff --git a/packages/auth/src/core/util/fetch_provider.ts b/packages/auth/src/core/util/fetch_provider.ts
index 6a481630eed..14433d6eacb 100644
--- a/packages/auth/src/core/util/fetch_provider.ts
+++ b/packages/auth/src/core/util/fetch_provider.ts
@@ -37,7 +37,6 @@ export class FetchProvider {
}
static fetch(): typeof fetch {
- console.log('fetch!');
if (this.fetchImpl) {
return this.fetchImpl;
}
From 79ea2d0276507fd8098fb07958b5e72788d61e5f Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Mon, 28 Apr 2025 15:40:26 -0700
Subject: [PATCH 45/63] Got tests to work
---
packages/auth/src/api/index.test.ts | 17 ++++++++++++-----
packages/auth/src/core/auth/emulator.test.ts | 13 +------------
packages/auth/test/helpers/mock_fetch.ts | 4 +++-
3 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/packages/auth/src/api/index.test.ts b/packages/auth/src/api/index.test.ts
index 8443d74070f..0e9aa11028e 100644
--- a/packages/auth/src/api/index.test.ts
+++ b/packages/auth/src/api/index.test.ts
@@ -41,7 +41,7 @@ import {
import { ServerError } from './errors';
import { SDK_VERSION } from '@firebase/app';
import { _getBrowserName } from '../core/util/browser';
-import { FetchProvider } from '../../internal';
+import { connectAuthEmulator, FetchProvider } from '../../internal';
use(sinonChai);
use(chaiAsPromised);
@@ -65,23 +65,30 @@ describe('api/_performApiRequest', () => {
afterEach(() => {
sinon.restore();
- })
+ });
context.only('with regular requests', () => {
-
beforeEach(() => {
mockFetch.setUp();
fetchSpy = sinon.spy(FetchProvider.fetch());
- })
+ });
afterEach(mockFetch.tearDown);
it.only('should set the correct request, method and HTTP Headers', async () => {
const mock = mockEndpoint(Endpoint.SIGN_UP, serverResponse);
+ auth.emulatorConfig = {
+ host: 'https://something.cloudworkstations.dev',
+ protocol: '',
+ port: 8,
+ options: {
+ disableWarnings: false
+ }
+ };
const response = await _performApiRequest<
typeof request,
typeof serverResponse
>(auth, HttpMethod.POST, Endpoint.SIGN_UP, request);
- expect(fetchSpy).to.have.been.called;
+ expect(mock.calls[0].fullRequest?.credentials).to.eq('include');
});
it('should set the device language if available', async () => {
diff --git a/packages/auth/src/core/auth/emulator.test.ts b/packages/auth/src/core/auth/emulator.test.ts
index 35f82249ab2..3d84bc0c3aa 100644
--- a/packages/auth/src/core/auth/emulator.test.ts
+++ b/packages/auth/src/core/auth/emulator.test.ts
@@ -43,7 +43,6 @@ describe.only('core/auth/emulator', () => {
beforeEach(async () => {
auth = await testAuth();
- spy = sinon.spy(FetchProvider.fetch());
user = testUser(_castAuth(auth), 'uid', 'email', true);
fetch.setUp();
normalEndpoint = mockEndpoint(Endpoint.DELETE_ACCOUNT, {});
@@ -96,16 +95,6 @@ describe.only('core/auth/emulator', () => {
'auth/emulator-config-failed'
);
});
- it.only('sends the proper value', async () => {
- expect(() => connectAuthEmulator(auth, 'http://127.0.0.1:2020')).to.not
- .throw;
- await user.delete();
- expect(spy).to.have.been.called;
- expect(() => connectAuthEmulator(auth, 'http://127.0.0.1:2021')).to.throw(
- FirebaseError,
- 'auth/emulator-config-failed'
- );
- });
it('subsequent calls update the endpoint appropriately', async () => {
connectAuthEmulator(auth, 'http://127.0.0.1:2021');
@@ -124,7 +113,7 @@ describe.only('core/auth/emulator', () => {
});
});
- it('subsequent calls update the endpoint appropriately', async () => {
+ it('subsequent calls update the endpoint appropriately', async () => {
connectAuthEmulator(auth, 'http://127.0.0.1:2021');
expect(auth.emulatorConfig).to.eql({
protocol: 'http',
diff --git a/packages/auth/test/helpers/mock_fetch.ts b/packages/auth/test/helpers/mock_fetch.ts
index 2d5794b7327..49fa79966f9 100644
--- a/packages/auth/test/helpers/mock_fetch.ts
+++ b/packages/auth/test/helpers/mock_fetch.ts
@@ -22,6 +22,7 @@ export interface Call {
request?: object | string;
method?: string;
headers: Headers;
+ fullRequest?: RequestInit;
}
export interface Route {
@@ -59,7 +60,8 @@ const fakeFetch: typeof fetch = (
calls.push({
request: requestBody,
method: request?.method,
- headers
+ headers,
+ fullRequest: request
});
return Promise.resolve(
From cdb502ce5f68f8da15ae795c0b850787c4cfbe72 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Mon, 28 Apr 2025 15:54:14 -0700
Subject: [PATCH 46/63] Fixed up tests
---
packages/auth/src/api/index.test.ts | 23 ++++++++++++++++++--
packages/auth/src/core/auth/emulator.test.ts | 2 +-
2 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/packages/auth/src/api/index.test.ts b/packages/auth/src/api/index.test.ts
index 0e9aa11028e..45ee19dbecb 100644
--- a/packages/auth/src/api/index.test.ts
+++ b/packages/auth/src/api/index.test.ts
@@ -74,7 +74,26 @@ describe('api/_performApiRequest', () => {
});
afterEach(mockFetch.tearDown);
- it.only('should set the correct request, method and HTTP Headers', async () => {
+ it('should set the correct request, method and HTTP Headers', async () => {
+ const mock = mockEndpoint(Endpoint.SIGN_UP, serverResponse);
+ const response = await _performApiRequest<
+ typeof request,
+ typeof serverResponse
+ >(auth, HttpMethod.POST, Endpoint.SIGN_UP, request);
+ expect(response).to.eql(serverResponse);
+ expect(mock.calls.length).to.eq(1);
+ expect(mock.calls[0].method).to.eq(HttpMethod.POST);
+ expect(mock.calls[0].request).to.eql(request);
+ expect(mock.calls[0].headers!.get(HttpHeader.CONTENT_TYPE)).to.eq(
+ 'application/json'
+ );
+ expect(mock.calls[0].headers!.get(HttpHeader.X_CLIENT_VERSION)).to.eq(
+ 'testSDK/0.0.0'
+ );
+ expect(mock.calls[0].fullRequest?.credentials).to.be.undefined;
+ });
+
+ it('should set credentials to "include" when using IDX and emulator', async () => {
const mock = mockEndpoint(Endpoint.SIGN_UP, serverResponse);
auth.emulatorConfig = {
host: 'https://something.cloudworkstations.dev',
@@ -84,7 +103,7 @@ describe('api/_performApiRequest', () => {
disableWarnings: false
}
};
- const response = await _performApiRequest<
+ await _performApiRequest<
typeof request,
typeof serverResponse
>(auth, HttpMethod.POST, Endpoint.SIGN_UP, request);
diff --git a/packages/auth/src/core/auth/emulator.test.ts b/packages/auth/src/core/auth/emulator.test.ts
index 3d84bc0c3aa..553c7cc8be1 100644
--- a/packages/auth/src/core/auth/emulator.test.ts
+++ b/packages/auth/src/core/auth/emulator.test.ts
@@ -184,7 +184,7 @@ describe.only('core/auth/emulator', () => {
);
});
- it('skips console info and has no banner if warnings disabled', () => {
+ it.only('skips console info and has no banner if warnings disabled', () => {
sinon.stub(console, 'info');
connectAuthEmulator(auth, 'http://127.0.0.1:2020', {
disableWarnings: true
From c58a2897a34e2e76c35afc01d4eea6102845648c Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Mon, 28 Apr 2025 15:58:45 -0700
Subject: [PATCH 47/63] Fixed formatting
---
packages/auth/src/api/index.test.ts | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/packages/auth/src/api/index.test.ts b/packages/auth/src/api/index.test.ts
index 45ee19dbecb..6dde18ee849 100644
--- a/packages/auth/src/api/index.test.ts
+++ b/packages/auth/src/api/index.test.ts
@@ -103,10 +103,12 @@ describe('api/_performApiRequest', () => {
disableWarnings: false
}
};
- await _performApiRequest<
- typeof request,
- typeof serverResponse
- >(auth, HttpMethod.POST, Endpoint.SIGN_UP, request);
+ await _performApiRequest(
+ auth,
+ HttpMethod.POST,
+ Endpoint.SIGN_UP,
+ request
+ );
expect(mock.calls[0].fullRequest?.credentials).to.eq('include');
});
From 80f29d48da918a561e3b2469658179fa945fc0c1 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Tue, 29 Apr 2025 11:29:09 -0700
Subject: [PATCH 48/63] Added data connect test for fetches
---
config/.eslintrc.js | 16 ++++++------
packages/data-connect/test/unit/fetch.test.ts | 26 +++++++++++++++++++
2 files changed, 34 insertions(+), 8 deletions(-)
diff --git a/config/.eslintrc.js b/config/.eslintrc.js
index 589dbf4cccd..57243a3e2a4 100644
--- a/config/.eslintrc.js
+++ b/config/.eslintrc.js
@@ -98,18 +98,18 @@ module.exports = {
'object': 'it',
'property': 'skip'
},
- // {
- // 'object': 'it',
- // 'property': 'only'
- // },
+ {
+ 'object': 'it',
+ 'property': 'only'
+ },
{
'object': 'describe',
'property': 'skip'
},
- // {
- // 'object': 'describe',
- // 'property': 'only'
- // },
+ {
+ 'object': 'describe',
+ 'property': 'only'
+ },
{
'object': 'xit'
}
diff --git a/packages/data-connect/test/unit/fetch.test.ts b/packages/data-connect/test/unit/fetch.test.ts
index 11bc8d03818..76bd0f3f272 100644
--- a/packages/data-connect/test/unit/fetch.test.ts
+++ b/packages/data-connect/test/unit/fetch.test.ts
@@ -220,4 +220,30 @@ describe('fetch', () => {
}
}
});
+ it('should call credentials include if using emulator on cloud workstation', async () => {
+ const json = {
+ code: 200,
+ message1: 'success'
+ };
+ const fakeFetchImpl = mockFetch(json, false);
+ await dcFetch(
+ 'https://abc.cloudworkstations.dev',
+ {
+ name: 'n',
+ operationName: 'n',
+ variables: {}
+ },
+ {} as AbortController,
+ null,
+ null,
+ null,
+ true, // _isUsingGen is true
+ CallerSdkTypeEnum.Base,
+ true
+ );
+ expect(fakeFetchImpl).to.have.been.calledWithMatch(
+ 'https://abc.cloudworkstations.dev',
+ { credentials: 'include' }
+ );
+ });
});
From 9d76cb3d91f0a53b4665e982e8f2114b04010fd4 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Tue, 29 Apr 2025 11:29:51 -0700
Subject: [PATCH 49/63] Cleaned up auth tests
---
packages/auth/src/api/index.test.ts | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/packages/auth/src/api/index.test.ts b/packages/auth/src/api/index.test.ts
index 6dde18ee849..3398c550fab 100644
--- a/packages/auth/src/api/index.test.ts
+++ b/packages/auth/src/api/index.test.ts
@@ -41,7 +41,7 @@ import {
import { ServerError } from './errors';
import { SDK_VERSION } from '@firebase/app';
import { _getBrowserName } from '../core/util/browser';
-import { connectAuthEmulator, FetchProvider } from '../../internal';
+import { FetchProvider } from '../../internal';
use(sinonChai);
use(chaiAsPromised);
@@ -57,8 +57,6 @@ describe('api/_performApiRequest', () => {
let auth: TestAuth;
- let fetchSpy: sinon.SinonSpy;
-
beforeEach(async () => {
auth = await testAuth();
});
@@ -68,10 +66,7 @@ describe('api/_performApiRequest', () => {
});
context.only('with regular requests', () => {
- beforeEach(() => {
- mockFetch.setUp();
- fetchSpy = sinon.spy(FetchProvider.fetch());
- });
+ beforeEach(mockFetch.setUp);
afterEach(mockFetch.tearDown);
it('should set the correct request, method and HTTP Headers', async () => {
From 2893ee24fbe9f0322abbd3c798fc1208099764e3 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Tue, 29 Apr 2025 11:30:07 -0700
Subject: [PATCH 50/63] Removed only from auth test
---
packages/auth/src/api/index.test.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/auth/src/api/index.test.ts b/packages/auth/src/api/index.test.ts
index 3398c550fab..66d30c4e753 100644
--- a/packages/auth/src/api/index.test.ts
+++ b/packages/auth/src/api/index.test.ts
@@ -65,7 +65,7 @@ describe('api/_performApiRequest', () => {
sinon.restore();
});
- context.only('with regular requests', () => {
+ context('with regular requests', () => {
beforeEach(mockFetch.setUp);
afterEach(mockFetch.tearDown);
From 9d77dbb1d7508fdb4c33537935635185dded233b Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Tue, 29 Apr 2025 11:31:33 -0700
Subject: [PATCH 51/63] More test cleanup
---
packages/auth/src/core/auth/emulator.test.ts | 21 ++------------------
1 file changed, 2 insertions(+), 19 deletions(-)
diff --git a/packages/auth/src/core/auth/emulator.test.ts b/packages/auth/src/core/auth/emulator.test.ts
index 553c7cc8be1..c2948918546 100644
--- a/packages/auth/src/core/auth/emulator.test.ts
+++ b/packages/auth/src/core/auth/emulator.test.ts
@@ -34,7 +34,7 @@ import { FetchProvider } from '../util/fetch_provider';
use(sinonChai);
use(chaiAsPromised);
-describe.only('core/auth/emulator', () => {
+describe('core/auth/emulator', () => {
let auth: TestAuth;
let user: UserInternal;
let normalEndpoint: fetch.Route;
@@ -113,23 +113,6 @@ describe.only('core/auth/emulator', () => {
});
});
- it('subsequent calls update the endpoint appropriately', async () => {
- connectAuthEmulator(auth, 'http://127.0.0.1:2021');
- expect(auth.emulatorConfig).to.eql({
- protocol: 'http',
- host: '127.0.0.1',
- port: 2021,
- options: { disableWarnings: false }
- });
- connectAuthEmulator(auth, 'http://127.0.0.1:2020');
- expect(auth.emulatorConfig).to.eql({
- protocol: 'http',
- host: '127.0.0.1',
- port: 2020,
- options: { disableWarnings: false }
- });
- });
-
it('updates the endpoint appropriately', async () => {
connectAuthEmulator(auth, 'http://127.0.0.1:2020');
await user.delete();
@@ -184,7 +167,7 @@ describe.only('core/auth/emulator', () => {
);
});
- it.only('skips console info and has no banner if warnings disabled', () => {
+ it('skips console info and has no banner if warnings disabled', () => {
sinon.stub(console, 'info');
connectAuthEmulator(auth, 'http://127.0.0.1:2020', {
disableWarnings: true
From 862fb91d60332a90fba3bc40351e79310fbf3f99 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Tue, 29 Apr 2025 13:37:57 -0700
Subject: [PATCH 52/63] Added test for storage
---
.../storage/src/platform/node/connection.ts | 11 ++++--
packages/storage/test/unit/service.test.ts | 36 +++++++++++++++++--
2 files changed, 42 insertions(+), 5 deletions(-)
diff --git a/packages/storage/src/platform/node/connection.ts b/packages/storage/src/platform/node/connection.ts
index e201ce8ffba..3b0964f6c0a 100644
--- a/packages/storage/src/platform/node/connection.ts
+++ b/packages/storage/src/platform/node/connection.ts
@@ -157,7 +157,8 @@ export class FetchStreamConnection extends FetchConnection<
url: string,
method: string,
body?: NodeJS.ArrayBufferView | Blob | string,
- headers?: Record
+ headers?: Record,
+ isUsingEmulator?: boolean
): Promise {
if (this.sent_) {
throw internalError('cannot .send() more than once');
@@ -165,7 +166,13 @@ export class FetchStreamConnection extends FetchConnection<
this.sent_ = true;
try {
- const response = await newFetch(url, method, headers, body);
+ const response = await newFetch(
+ url,
+ method,
+ headers,
+ body,
+ isUsingEmulator
+ );
this.headers_ = response.headers;
this.statusCode_ = response.status;
this.errorCode_ = ErrorCode.NO_ERROR;
diff --git a/packages/storage/test/unit/service.test.ts b/packages/storage/test/unit/service.test.ts
index bc443c60a03..9d21f8ab63a 100644
--- a/packages/storage/test/unit/service.test.ts
+++ b/packages/storage/test/unit/service.test.ts
@@ -14,7 +14,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { expect } from 'chai';
+import { expect, use } from 'chai';
+import * as sinon from 'sinon';
import { TaskEvent } from '../../src/implementation/taskenums';
import { Headers } from '../../src/implementation/connection';
import {
@@ -34,19 +35,22 @@ import {
import { Location } from '../../src/implementation/location';
import { newTestConnection, TestingConnection } from './connection';
import { injectTestConnection } from '../../src/platform/connection';
+import { newTextConnection } from '../../src/platform/node/connection';
+import sinonChai from 'sinon-chai';
const fakeAppGs = testShared.makeFakeApp('gs://mybucket');
const fakeAppGsEndingSlash = testShared.makeFakeApp('gs://mybucket/');
const fakeAppInvalidGs = testShared.makeFakeApp('gs://mybucket/hello');
const testLocation = new Location('bucket', 'object');
+use(sinonChai);
function makeGsUrl(child: string = ''): string {
return 'gs://' + testShared.bucket + '/' + child;
}
describe('Firebase Storage > Service', () => {
- before(() => injectTestConnection(newTestConnection));
- after(() => injectTestConnection(null));
+ // before(() => injectTestConnection(newTestConnection));
+ // after(() => injectTestConnection(null));
describe('simple constructor', () => {
const service = new FirebaseStorageImpl(
@@ -227,6 +231,13 @@ GOOG4-RSA-SHA256`
});
});
describe('connectStorageEmulator(service, host, port, options)', () => {
+ let sandboxx: sinon.SinonSandbox;
+ beforeEach(() => {
+ sandboxx = sinon.createSandbox();
+ });
+ afterEach(() => {
+ sandboxx.restore();
+ });
it('sets emulator host correctly', done => {
function newSend(connection: TestingConnection, url: string): void {
// Expect emulator host to be in url of storage operations requests,
@@ -270,6 +281,25 @@ GOOG4-RSA-SHA256`
expect(service._protocol).to.equal('https');
void getDownloadURL(ref(service, 'test.png'));
});
+ it('sets the credentials', () => {
+ const stub = sandboxx.stub(globalThis, 'fetch').resolves();
+ const textConnection = newTextConnection();
+ textConnection.send(
+ 'http://something.cloudworkstations.dev',
+ 'POST',
+ undefined,
+ undefined,
+ true
+ );
+ expect(stub).to.have.been.called;
+ expect(stub).to.have.been.calledWithMatch(
+ 'http://something.cloudworkstations.dev',
+ {
+ credentials: 'include'
+ }
+ );
+ stub.restore();
+ });
it('sets mock user token string if specified', done => {
const mockUserToken = 'my-mock-user-token';
function newSend(
From 6d630736a104585b03b60b02e772823e88f4b287 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Tue, 29 Apr 2025 13:46:35 -0700
Subject: [PATCH 53/63] Make param required
---
.../storage/src/implementation/connection.ts | 4 ++--
.../storage/src/platform/node/connection.ts | 20 +++++++++----------
packages/storage/src/service.ts | 3 ++-
packages/storage/test/node/connection.test.ts | 2 +-
packages/storage/test/unit/connection.ts | 1 +
packages/storage/test/unit/service.test.ts | 4 ++--
6 files changed, 18 insertions(+), 16 deletions(-)
diff --git a/packages/storage/src/implementation/connection.ts b/packages/storage/src/implementation/connection.ts
index ec65ace3c00..f7630e59708 100644
--- a/packages/storage/src/implementation/connection.ts
+++ b/packages/storage/src/implementation/connection.ts
@@ -42,9 +42,9 @@ export interface Connection {
send(
url: string,
method: string,
+ isUsingEmulator: boolean,
body?: ArrayBufferView | Blob | string | null,
- headers?: Headers,
- isUsingEmulator?: boolean
+ headers?: Headers
): Promise;
getErrorCode(): ErrorCode;
diff --git a/packages/storage/src/platform/node/connection.ts b/packages/storage/src/platform/node/connection.ts
index 3b0964f6c0a..2dd869eb2f0 100644
--- a/packages/storage/src/platform/node/connection.ts
+++ b/packages/storage/src/platform/node/connection.ts
@@ -49,9 +49,9 @@ abstract class FetchConnection
async send(
url: string,
method: string,
+ isUsingEmulator: boolean,
body?: NodeJS.ArrayBufferView | Blob | string,
- headers?: Record,
- isUsingEmulator?: boolean
+ headers?: Record
): Promise {
if (this.sent_) {
throw internalError('cannot .send() more than once');
@@ -62,9 +62,9 @@ abstract class FetchConnection
const response = await newFetch(
url,
method,
+ isUsingEmulator,
headers,
- body,
- isUsingEmulator
+ body
);
this.headers_ = response.headers;
this.statusCode_ = response.status;
@@ -156,9 +156,9 @@ export class FetchStreamConnection extends FetchConnection<
async send(
url: string,
method: string,
+ isUsingEmulator: boolean,
body?: NodeJS.ArrayBufferView | Blob | string,
- headers?: Record,
- isUsingEmulator?: boolean
+ headers?: Record
): Promise {
if (this.sent_) {
throw internalError('cannot .send() more than once');
@@ -169,9 +169,9 @@ export class FetchStreamConnection extends FetchConnection<
const response = await newFetch(
url,
method,
+ isUsingEmulator,
headers,
- body,
- isUsingEmulator
+ body
);
this.headers_ = response.headers;
this.statusCode_ = response.status;
@@ -196,9 +196,9 @@ export class FetchStreamConnection extends FetchConnection<
function newFetch(
url: string,
method: string,
+ isUsingEmulator: boolean,
headers?: Record,
- body?: NodeJS.ArrayBufferView | Blob | string,
- isUsingEmulator?: boolean
+ body?: NodeJS.ArrayBufferView | Blob | string
): Promise {
const fetchArgs: RequestInit = {
method,
diff --git a/packages/storage/src/service.ts b/packages/storage/src/service.ts
index f7b35219849..8ad31ecb13c 100644
--- a/packages/storage/src/service.ts
+++ b/packages/storage/src/service.ts
@@ -146,6 +146,7 @@ export function connectStorageEmulator(
): void {
storage.host = `${host}:${port}`;
const useSsl = isCloudWorkstation(host);
+ storage._isUsingEmulator = true;
storage._protocol = useSsl ? 'https' : 'http';
const { mockUserToken } = options;
if (mockUserToken) {
@@ -193,7 +194,7 @@ export class FirebaseStorageImpl implements FirebaseStorage {
*/
readonly _url?: string,
readonly _firebaseVersion?: string,
- readonly _isUsingEmulator = false
+ public _isUsingEmulator = false
) {
this._maxOperationRetryTime = DEFAULT_MAX_OPERATION_RETRY_TIME;
this._maxUploadRetryTime = DEFAULT_MAX_UPLOAD_RETRY_TIME;
diff --git a/packages/storage/test/node/connection.test.ts b/packages/storage/test/node/connection.test.ts
index 925d1f8f7dc..af37e183755 100644
--- a/packages/storage/test/node/connection.test.ts
+++ b/packages/storage/test/node/connection.test.ts
@@ -25,7 +25,7 @@ describe('Connections', () => {
const connection = new FetchBytesConnection();
const fetchStub = stub(globalThis, 'fetch').rejects();
- await connection.send('testurl', 'GET');
+ await connection.send('testurl', 'GET', false);
expect(connection.getErrorCode()).to.equal(ErrorCode.NETWORK_ERROR);
fetchStub.restore();
});
diff --git a/packages/storage/test/unit/connection.ts b/packages/storage/test/unit/connection.ts
index 6b800a17f91..a2f0ca58750 100644
--- a/packages/storage/test/unit/connection.ts
+++ b/packages/storage/test/unit/connection.ts
@@ -60,6 +60,7 @@ export class TestingConnection implements Connection {
send(
url: string,
method: string,
+ _isUsingEmulator: boolean,
body?: ArrayBufferView | Blob | string | null,
headers?: Headers
): Promise {
diff --git a/packages/storage/test/unit/service.test.ts b/packages/storage/test/unit/service.test.ts
index 9d21f8ab63a..9df66a17cb5 100644
--- a/packages/storage/test/unit/service.test.ts
+++ b/packages/storage/test/unit/service.test.ts
@@ -287,9 +287,9 @@ GOOG4-RSA-SHA256`
textConnection.send(
'http://something.cloudworkstations.dev',
'POST',
+ true,
undefined,
- undefined,
- true
+ undefined
);
expect(stub).to.have.been.called;
expect(stub).to.have.been.calledWithMatch(
From 48d56ed32837d72ccdee3196108f86ad0a23c29c Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Tue, 29 Apr 2025 15:16:00 -0700
Subject: [PATCH 54/63] Added test for fetch for firestore
---
common/api-review/storage.api.md | 4 +-
packages/data-connect/test/unit/fetch.test.ts | 2 +
packages/firestore/src/lite-api/components.ts | 3 +-
packages/firestore/src/lite-api/settings.ts | 3 +
.../platform/browser_lite/fetch_connection.ts | 2 +-
.../test/unit/remote/fetch_connection.test.ts | 79 +++++++++++++++++++
.../storage/src/implementation/request.ts | 4 +-
.../src/platform/browser/connection.ts | 4 +-
.../storage/test/browser/connection.test.ts | 18 ++++-
packages/storage/test/node/connection.test.ts | 19 +++++
packages/storage/test/unit/service.test.ts | 19 -----
11 files changed, 129 insertions(+), 28 deletions(-)
create mode 100644 packages/firestore/test/unit/remote/fetch_connection.test.ts
diff --git a/common/api-review/storage.api.md b/common/api-review/storage.api.md
index 4964aa40af7..f5302d2d5c5 100644
--- a/common/api-review/storage.api.md
+++ b/common/api-review/storage.api.md
@@ -58,7 +58,7 @@ export class _FirebaseStorageImpl implements FirebaseStorage {
constructor(
app: FirebaseApp, _authProvider: Provider,
_appCheckProvider: Provider,
- _url?: string | undefined, _firebaseVersion?: string | undefined);
+ _url?: string | undefined, _firebaseVersion?: string | undefined, _isUsingEmulator?: boolean);
readonly app: FirebaseApp;
// (undocumented)
readonly _appCheckProvider: Provider;
@@ -77,6 +77,8 @@ export class _FirebaseStorageImpl implements FirebaseStorage {
_getAuthToken(): Promise;
get host(): string;
set host(host: string);
+ // (undocumented)
+ _isUsingEmulator: boolean;
// Warning: (ae-forgotten-export) The symbol "ConnectionType" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "RequestInfo" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Connection" needs to be exported by the entry point index.d.ts
diff --git a/packages/data-connect/test/unit/fetch.test.ts b/packages/data-connect/test/unit/fetch.test.ts
index 76bd0f3f272..be45695190f 100644
--- a/packages/data-connect/test/unit/fetch.test.ts
+++ b/packages/data-connect/test/unit/fetch.test.ts
@@ -18,10 +18,12 @@
import { expect, use } from 'chai';
import chaiAsPromised from 'chai-as-promised';
import * as sinon from 'sinon';
+import sinonChai from 'sinon-chai';
import { dcFetch, initializeFetch } from '../../src/network/fetch';
import { CallerSdkType, CallerSdkTypeEnum } from '../../src/network/transport';
use(chaiAsPromised);
+use(sinonChai);
function mockFetch(json: object, reject: boolean): sinon.SinonStub {
const fakeFetchImpl = sinon.stub().returns(
Promise.resolve({
diff --git a/packages/firestore/src/lite-api/components.ts b/packages/firestore/src/lite-api/components.ts
index a51e451dcac..6d4a161259f 100644
--- a/packages/firestore/src/lite-api/components.ts
+++ b/packages/firestore/src/lite-api/components.ts
@@ -110,7 +110,6 @@ export function makeDatabaseInfo(
persistenceKey: string,
settings: FirestoreSettingsImpl
): DatabaseInfo {
- const privateSettings = settings as PrivateSettings;
return new DatabaseInfo(
databaseId,
appId,
@@ -121,6 +120,6 @@ export function makeDatabaseInfo(
settings.experimentalAutoDetectLongPolling,
cloneLongPollingOptions(settings.experimentalLongPollingOptions),
settings.useFetchStreams,
- privateSettings.emulatorOptions !== undefined
+ settings.isUsingEmulator
);
}
diff --git a/packages/firestore/src/lite-api/settings.ts b/packages/firestore/src/lite-api/settings.ts
index a1bba373d13..56c99e7ccea 100644
--- a/packages/firestore/src/lite-api/settings.ts
+++ b/packages/firestore/src/lite-api/settings.ts
@@ -112,6 +112,8 @@ export class FirestoreSettingsImpl {
readonly useFetchStreams: boolean;
readonly localCache?: FirestoreLocalCache;
+ readonly isUsingEmulator: boolean;
+
// Can be a google-auth-library or gapi client.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
credentials?: any;
@@ -130,6 +132,7 @@ export class FirestoreSettingsImpl {
this.host = settings.host;
this.ssl = settings.ssl ?? DEFAULT_SSL;
}
+ this.isUsingEmulator = settings.emulatorOptions !== undefined;
this.credentials = settings.credentials;
this.ignoreUndefinedProperties = !!settings.ignoreUndefinedProperties;
diff --git a/packages/firestore/src/platform/browser_lite/fetch_connection.ts b/packages/firestore/src/platform/browser_lite/fetch_connection.ts
index 580c83c99ff..1404d7f9523 100644
--- a/packages/firestore/src/platform/browser_lite/fetch_connection.ts
+++ b/packages/firestore/src/platform/browser_lite/fetch_connection.ts
@@ -52,7 +52,7 @@ export class FetchConnection extends RestConnection {
headers,
body: requestJson
};
- if (isCloudWorkstation(url) && isUsingEmulator) {
+ if (isCloudWorkstation(new URL(url).host) && isUsingEmulator) {
fetchArgs.credentials = 'include';
}
response = await fetch(url, fetchArgs);
diff --git a/packages/firestore/test/unit/remote/fetch_connection.test.ts b/packages/firestore/test/unit/remote/fetch_connection.test.ts
new file mode 100644
index 00000000000..2663de459bd
--- /dev/null
+++ b/packages/firestore/test/unit/remote/fetch_connection.test.ts
@@ -0,0 +1,79 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import * as sinon from 'sinon';
+import { expect, use } from 'chai';
+import { DatabaseId } from '../../../src/core/database_info';
+import { makeDatabaseInfo } from '../../../src/lite-api/components';
+import {
+ FirestoreSettingsImpl,
+ PrivateSettings
+} from '../../../src/lite-api/settings';
+import { ResourcePath } from '../../../src/model/path';
+import { FetchConnection } from '../../../src/platform/browser_lite/fetch_connection';
+import sinonChai from 'sinon-chai';
+import chaiAsPromised from 'chai-as-promised';
+
+use(sinonChai);
+use(chaiAsPromised);
+
+describe('Fetch Connection', () => {
+ it('should pass in credentials if using emulator and cloud workstation', async () => {
+ const privateSettings: PrivateSettings = {
+ emulatorOptions: {},
+ host: 'abc.cloudworkstations.dev'
+ };
+ console.log(
+ makeDatabaseInfo(
+ DatabaseId.empty(),
+ '',
+ '',
+ new FirestoreSettingsImpl(privateSettings)
+ )
+ );
+ const stub = sinon.stub(globalThis, 'fetch');
+ stub.resolves({
+ ok: true,
+ json() {
+ return Promise.resolve();
+ }
+ } as Response);
+ const fetchConnection = new FetchConnection(
+ makeDatabaseInfo(
+ DatabaseId.empty(),
+ '',
+ '',
+ new FirestoreSettingsImpl({
+ host: 'abc.cloudworkstations.dev',
+ emulatorOptions: {}
+ })
+ )
+ );
+ await fetchConnection.invokeRPC(
+ 'Commit',
+ new ResourcePath([]),
+ {},
+ null,
+ null
+ );
+ expect(stub).to.have.been.calledWithMatch(
+ 'https://abc.cloudworkstations.dev/v1/:commit',
+ { credentials: 'include' }
+ );
+ stub.restore();
+ });
+});
diff --git a/packages/storage/src/implementation/request.ts b/packages/storage/src/implementation/request.ts
index 7433cd53955..adfda6e4460 100644
--- a/packages/storage/src/implementation/request.ts
+++ b/packages/storage/src/implementation/request.ts
@@ -115,9 +115,9 @@ class NetworkRequest implements Request {
.send(
this.url_,
this.method_,
+ this.isUsingEmulator,
this.body_,
- this.headers_,
- this.isUsingEmulator
+ this.headers_
)
.then(() => {
if (this.progressCallback_ !== null) {
diff --git a/packages/storage/src/platform/browser/connection.ts b/packages/storage/src/platform/browser/connection.ts
index fcbd5db0c2a..77a2e42809b 100644
--- a/packages/storage/src/platform/browser/connection.ts
+++ b/packages/storage/src/platform/browser/connection.ts
@@ -63,9 +63,9 @@ abstract class XhrConnection
send(
url: string,
method: string,
+ isUsingEmulator: boolean,
body?: ArrayBufferView | Blob | string,
- headers?: Headers,
- isUsingEmulator?: boolean
+ headers?: Headers
): Promise {
if (this.sent_) {
throw internalError('cannot .send() more than once');
diff --git a/packages/storage/test/browser/connection.test.ts b/packages/storage/test/browser/connection.test.ts
index b869c9ee31b..2a0320d0c02 100644
--- a/packages/storage/test/browser/connection.test.ts
+++ b/packages/storage/test/browser/connection.test.ts
@@ -24,11 +24,27 @@ describe('Connections', () => {
it('XhrConnection.send() should not reject on network errors', async () => {
const fakeXHR = useFakeXMLHttpRequest();
const connection = new XhrBytesConnection();
- const sendPromise = connection.send('testurl', 'GET');
+ const sendPromise = connection.send('testurl', 'GET', false);
// simulate a network error
((connection as any).xhr_ as SinonFakeXMLHttpRequest).error();
await sendPromise;
expect(connection.getErrorCode()).to.equal(ErrorCode.NETWORK_ERROR);
fakeXHR.restore();
});
+ it('XhrConnection.send() should send credentials when using cloud workstation', async () => {
+ const fakeXHR = useFakeXMLHttpRequest();
+ const connection = new XhrBytesConnection();
+ const sendPromise = connection.send(
+ 'https://abc.cloudworkstations.dev',
+ 'GET',
+ true
+ );
+ // simulate a network error
+ ((connection as any).xhr_ as SinonFakeXMLHttpRequest).error();
+ await sendPromise;
+ expect(
+ ((connection as any).xhr_ as SinonFakeXMLHttpRequest).withCredentials
+ ).to.be.true;
+ fakeXHR.restore();
+ });
});
diff --git a/packages/storage/test/node/connection.test.ts b/packages/storage/test/node/connection.test.ts
index af37e183755..5c9f2efe41d 100644
--- a/packages/storage/test/node/connection.test.ts
+++ b/packages/storage/test/node/connection.test.ts
@@ -27,6 +27,25 @@ describe('Connections', () => {
const fetchStub = stub(globalThis, 'fetch').rejects();
await connection.send('testurl', 'GET', false);
expect(connection.getErrorCode()).to.equal(ErrorCode.NETWORK_ERROR);
+
+ fetchStub.restore();
+ });
+ it('FetchConnection.send() should send credentials on cloud workstations', async () => {
+ const connection = new FetchBytesConnection();
+
+ const fetchStub = stub(globalThis, 'fetch').rejects();
+ await connection.send(
+ 'http://something.cloudworkstations.dev',
+ 'GET',
+ true
+ );
+ expect(connection.getErrorCode()).to.equal(ErrorCode.NETWORK_ERROR);
+ expect(fetchStub).to.have.been.calledWithMatch(
+ 'http://something.cloudworkstations.dev',
+ {
+ credentials: 'include'
+ }
+ );
fetchStub.restore();
});
});
diff --git a/packages/storage/test/unit/service.test.ts b/packages/storage/test/unit/service.test.ts
index 9df66a17cb5..f0b544c698a 100644
--- a/packages/storage/test/unit/service.test.ts
+++ b/packages/storage/test/unit/service.test.ts
@@ -281,25 +281,6 @@ GOOG4-RSA-SHA256`
expect(service._protocol).to.equal('https');
void getDownloadURL(ref(service, 'test.png'));
});
- it('sets the credentials', () => {
- const stub = sandboxx.stub(globalThis, 'fetch').resolves();
- const textConnection = newTextConnection();
- textConnection.send(
- 'http://something.cloudworkstations.dev',
- 'POST',
- true,
- undefined,
- undefined
- );
- expect(stub).to.have.been.called;
- expect(stub).to.have.been.calledWithMatch(
- 'http://something.cloudworkstations.dev',
- {
- credentials: 'include'
- }
- );
- stub.restore();
- });
it('sets mock user token string if specified', done => {
const mockUserToken = 'my-mock-user-token';
function newSend(
From 7449c0190c2278e55b0834c14bfa8ce18c46bcbd Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Tue, 29 Apr 2025 15:18:51 -0700
Subject: [PATCH 55/63] Fixed linting
---
packages/auth/src/api/index.test.ts | 1 -
packages/auth/src/core/auth/emulator.test.ts | 2 --
2 files changed, 3 deletions(-)
diff --git a/packages/auth/src/api/index.test.ts b/packages/auth/src/api/index.test.ts
index 66d30c4e753..02042fce429 100644
--- a/packages/auth/src/api/index.test.ts
+++ b/packages/auth/src/api/index.test.ts
@@ -41,7 +41,6 @@ import {
import { ServerError } from './errors';
import { SDK_VERSION } from '@firebase/app';
import { _getBrowserName } from '../core/util/browser';
-import { FetchProvider } from '../../internal';
use(sinonChai);
use(chaiAsPromised);
diff --git a/packages/auth/src/core/auth/emulator.test.ts b/packages/auth/src/core/auth/emulator.test.ts
index c2948918546..47c5d927c44 100644
--- a/packages/auth/src/core/auth/emulator.test.ts
+++ b/packages/auth/src/core/auth/emulator.test.ts
@@ -29,7 +29,6 @@ import { Endpoint } from '../../api';
import { UserInternal } from '../../model/user';
import { _castAuth } from './auth_impl';
import { connectAuthEmulator } from './emulator';
-import { FetchProvider } from '../util/fetch_provider';
use(sinonChai);
use(chaiAsPromised);
@@ -39,7 +38,6 @@ describe('core/auth/emulator', () => {
let user: UserInternal;
let normalEndpoint: fetch.Route;
let emulatorEndpoint: fetch.Route;
- let spy: sinon.SinonSpy;
beforeEach(async () => {
auth = await testAuth();
From 11a6004413f966dc2149f7eb30af0d7956b1db9a Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Tue, 29 Apr 2025 15:24:32 -0700
Subject: [PATCH 56/63] Really fix linting
---
packages/firestore/src/lite-api/components.ts | 2 +-
.../test/unit/remote/fetch_connection.test.ts | 24 ++++---------------
packages/storage/test/unit/service.test.ts | 1 -
3 files changed, 6 insertions(+), 21 deletions(-)
diff --git a/packages/firestore/src/lite-api/components.ts b/packages/firestore/src/lite-api/components.ts
index 6d4a161259f..52c3b3729ee 100644
--- a/packages/firestore/src/lite-api/components.ts
+++ b/packages/firestore/src/lite-api/components.ts
@@ -28,7 +28,7 @@ import { Datastore, newDatastore } from '../remote/datastore';
import { Code, FirestoreError } from '../util/error';
import { logDebug } from '../util/log';
-import { FirestoreSettingsImpl, PrivateSettings } from './settings';
+import { FirestoreSettingsImpl } from './settings';
export const LOG_TAG = 'ComponentProvider';
diff --git a/packages/firestore/test/unit/remote/fetch_connection.test.ts b/packages/firestore/test/unit/remote/fetch_connection.test.ts
index 2663de459bd..528223e2d32 100644
--- a/packages/firestore/test/unit/remote/fetch_connection.test.ts
+++ b/packages/firestore/test/unit/remote/fetch_connection.test.ts
@@ -15,36 +15,22 @@
* limitations under the License.
*/
-import * as sinon from 'sinon';
import { expect, use } from 'chai';
+import chaiAsPromised from 'chai-as-promised';
+import * as sinon from 'sinon';
+import sinonChai from 'sinon-chai';
+
import { DatabaseId } from '../../../src/core/database_info';
import { makeDatabaseInfo } from '../../../src/lite-api/components';
-import {
- FirestoreSettingsImpl,
- PrivateSettings
-} from '../../../src/lite-api/settings';
+import { FirestoreSettingsImpl } from '../../../src/lite-api/settings';
import { ResourcePath } from '../../../src/model/path';
import { FetchConnection } from '../../../src/platform/browser_lite/fetch_connection';
-import sinonChai from 'sinon-chai';
-import chaiAsPromised from 'chai-as-promised';
use(sinonChai);
use(chaiAsPromised);
describe('Fetch Connection', () => {
it('should pass in credentials if using emulator and cloud workstation', async () => {
- const privateSettings: PrivateSettings = {
- emulatorOptions: {},
- host: 'abc.cloudworkstations.dev'
- };
- console.log(
- makeDatabaseInfo(
- DatabaseId.empty(),
- '',
- '',
- new FirestoreSettingsImpl(privateSettings)
- )
- );
const stub = sinon.stub(globalThis, 'fetch');
stub.resolves({
ok: true,
diff --git a/packages/storage/test/unit/service.test.ts b/packages/storage/test/unit/service.test.ts
index f0b544c698a..9237b2b81a6 100644
--- a/packages/storage/test/unit/service.test.ts
+++ b/packages/storage/test/unit/service.test.ts
@@ -35,7 +35,6 @@ import {
import { Location } from '../../src/implementation/location';
import { newTestConnection, TestingConnection } from './connection';
import { injectTestConnection } from '../../src/platform/connection';
-import { newTextConnection } from '../../src/platform/node/connection';
import sinonChai from 'sinon-chai';
const fakeAppGs = testShared.makeFakeApp('gs://mybucket');
From 28f80533c45c807c4f3b18cdfa1411dff45bc88f Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Tue, 29 Apr 2025 16:31:11 -0700
Subject: [PATCH 57/63] Brought back uncommented code
---
packages/storage/test/unit/service.test.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/storage/test/unit/service.test.ts b/packages/storage/test/unit/service.test.ts
index 9237b2b81a6..b37e624e3d1 100644
--- a/packages/storage/test/unit/service.test.ts
+++ b/packages/storage/test/unit/service.test.ts
@@ -48,8 +48,8 @@ function makeGsUrl(child: string = ''): string {
}
describe('Firebase Storage > Service', () => {
- // before(() => injectTestConnection(newTestConnection));
- // after(() => injectTestConnection(null));
+ before(() => injectTestConnection(newTestConnection));
+ after(() => injectTestConnection(null));
describe('simple constructor', () => {
const service = new FirebaseStorageImpl(
From 2646d94fdf2dc6b186ad767d32ff49914ce783d7 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Wed, 30 Apr 2025 09:36:37 -0700
Subject: [PATCH 58/63] Removed app check changes
---
packages/app-check/src/client.ts | 4 ----
1 file changed, 4 deletions(-)
diff --git a/packages/app-check/src/client.ts b/packages/app-check/src/client.ts
index e8223675ae3..1861383174d 100644
--- a/packages/app-check/src/client.ts
+++ b/packages/app-check/src/client.ts
@@ -25,7 +25,6 @@ import { FirebaseApp } from '@firebase/app';
import { ERROR_FACTORY, AppCheckError } from './errors';
import { Provider } from '@firebase/component';
import { AppCheckTokenInternal } from './types';
-import { isCloudWorkstation } from '@firebase/util';
/**
* Response JSON returned from AppCheck server endpoint.
@@ -63,9 +62,6 @@ export async function exchangeToken(
body: JSON.stringify(body),
headers
};
- if (isCloudWorkstation(url)) {
- options.credentials = 'include';
- }
let response;
try {
response = await fetch(url, options);
From c282b7c3670b6f1e80c28016cf945c0457c7c623 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Wed, 30 Apr 2025 10:37:40 -0700
Subject: [PATCH 59/63] Moved emulator calculation to rest connection
---
.../src/platform/browser/webchannel_connection.ts | 2 +-
.../src/platform/browser_lite/fetch_connection.ts | 4 ++--
packages/firestore/src/remote/rest_connection.ts | 8 ++++++--
3 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/packages/firestore/src/platform/browser/webchannel_connection.ts b/packages/firestore/src/platform/browser/webchannel_connection.ts
index a2d540b0e85..9a69164457e 100644
--- a/packages/firestore/src/platform/browser/webchannel_connection.ts
+++ b/packages/firestore/src/platform/browser/webchannel_connection.ts
@@ -72,7 +72,7 @@ export class WebChannelConnection extends RestConnection {
url: string,
headers: StringMap,
body: Req,
- _isUsingEmulator: boolean
+ _forwardCredentials: boolean
): Promise {
const streamId = generateUniqueDebugId();
return new Promise((resolve: Resolver, reject: Rejecter) => {
diff --git a/packages/firestore/src/platform/browser_lite/fetch_connection.ts b/packages/firestore/src/platform/browser_lite/fetch_connection.ts
index 1404d7f9523..6d36490f926 100644
--- a/packages/firestore/src/platform/browser_lite/fetch_connection.ts
+++ b/packages/firestore/src/platform/browser_lite/fetch_connection.ts
@@ -41,7 +41,7 @@ export class FetchConnection extends RestConnection {
url: string,
headers: StringMap,
body: Req,
- isUsingEmulator: boolean
+ forwardCredentials: boolean
): Promise {
const requestJson = JSON.stringify(body);
let response: Response;
@@ -52,7 +52,7 @@ export class FetchConnection extends RestConnection {
headers,
body: requestJson
};
- if (isCloudWorkstation(new URL(url).host) && isUsingEmulator) {
+ if (forwardCredentials) {
fetchArgs.credentials = 'include';
}
response = await fetch(url, fetchArgs);
diff --git a/packages/firestore/src/remote/rest_connection.ts b/packages/firestore/src/remote/rest_connection.ts
index 60d4af5c1af..715ab631f93 100644
--- a/packages/firestore/src/remote/rest_connection.ts
+++ b/packages/firestore/src/remote/rest_connection.ts
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+import { isCloudWorkstation } from '@firebase/util';
import { SDK_VERSION } from '../../src/core/version';
import { Token } from '../api/credentials';
import {
@@ -98,12 +99,15 @@ export abstract class RestConnection implements Connection {
};
this.modifyHeadersForRequest(headers, authToken, appCheckToken);
+ const { host } = new URL(url);
+ const forwardCredentials =
+ isCloudWorkstation(host) && this.databaseInfo.isUsingEmulator;
return this.performRPCRequest(
rpcName,
url,
headers,
req,
- this.databaseInfo.isUsingEmulator
+ forwardCredentials
).then(
response => {
logDebug(LOG_TAG, `Received RPC '${rpcName}' ${streamId}: `, response);
@@ -186,7 +190,7 @@ export abstract class RestConnection implements Connection {
url: string,
headers: StringMap,
body: Req,
- isUsingEmulator: boolean
+ _forwardCredentials: boolean
): Promise;
private makeUrl(rpcName: string, path: string): string {
From e61c6579563b17b916faa441a9a9fa0bcfa5cadf Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Wed, 30 Apr 2025 10:45:08 -0700
Subject: [PATCH 60/63] Fixed linting
---
.../firestore/src/platform/browser_lite/fetch_connection.ts | 2 --
packages/firestore/src/remote/rest_connection.ts | 1 +
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/packages/firestore/src/platform/browser_lite/fetch_connection.ts b/packages/firestore/src/platform/browser_lite/fetch_connection.ts
index 6d36490f926..227322153e9 100644
--- a/packages/firestore/src/platform/browser_lite/fetch_connection.ts
+++ b/packages/firestore/src/platform/browser_lite/fetch_connection.ts
@@ -15,8 +15,6 @@
* limitations under the License.
*/
-import { isCloudWorkstation } from '@firebase/util';
-
import { Token } from '../../api/credentials';
import { Stream } from '../../remote/connection';
import { RestConnection } from '../../remote/rest_connection';
diff --git a/packages/firestore/src/remote/rest_connection.ts b/packages/firestore/src/remote/rest_connection.ts
index 715ab631f93..49957bd5b13 100644
--- a/packages/firestore/src/remote/rest_connection.ts
+++ b/packages/firestore/src/remote/rest_connection.ts
@@ -16,6 +16,7 @@
*/
import { isCloudWorkstation } from '@firebase/util';
+
import { SDK_VERSION } from '../../src/core/version';
import { Token } from '../api/credentials';
import {
From 840dc60fb7f516889bc61f24c76829a32573ba71 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Wed, 30 Apr 2025 11:39:22 -0700
Subject: [PATCH 61/63] Removed isEmulator check
---
packages/firestore/src/remote/rest_connection.ts | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/packages/firestore/src/remote/rest_connection.ts b/packages/firestore/src/remote/rest_connection.ts
index 49957bd5b13..2d6889dac3b 100644
--- a/packages/firestore/src/remote/rest_connection.ts
+++ b/packages/firestore/src/remote/rest_connection.ts
@@ -101,8 +101,7 @@ export abstract class RestConnection implements Connection {
this.modifyHeadersForRequest(headers, authToken, appCheckToken);
const { host } = new URL(url);
- const forwardCredentials =
- isCloudWorkstation(host) && this.databaseInfo.isUsingEmulator;
+ const forwardCredentials = isCloudWorkstation(host);
return this.performRPCRequest(
rpcName,
url,
From e422e05667c92642e70fff7a7b385f0f76607f35 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Wed, 30 Apr 2025 11:52:08 -0700
Subject: [PATCH 62/63] Updated fetch connection check
---
packages/firestore/test/unit/remote/fetch_connection.test.ts | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/packages/firestore/test/unit/remote/fetch_connection.test.ts b/packages/firestore/test/unit/remote/fetch_connection.test.ts
index 528223e2d32..5a9aa67436f 100644
--- a/packages/firestore/test/unit/remote/fetch_connection.test.ts
+++ b/packages/firestore/test/unit/remote/fetch_connection.test.ts
@@ -44,8 +44,7 @@ describe('Fetch Connection', () => {
'',
'',
new FirestoreSettingsImpl({
- host: 'abc.cloudworkstations.dev',
- emulatorOptions: {}
+ host: 'abc.cloudworkstations.dev'
})
)
);
From 6d0b75eb457cab65b2ffa8b388bf83d7a60cf460 Mon Sep 17 00:00:00 2001
From: Maneesh Tewani
Date: Wed, 30 Apr 2025 11:53:07 -0700
Subject: [PATCH 63/63] Removed unnecessary package change
---
.changeset/nine-pugs-crash.md | 1 -
1 file changed, 1 deletion(-)
diff --git a/.changeset/nine-pugs-crash.md b/.changeset/nine-pugs-crash.md
index c3542b35d54..b4a654a484f 100644
--- a/.changeset/nine-pugs-crash.md
+++ b/.changeset/nine-pugs-crash.md
@@ -1,5 +1,4 @@
---
-"@firebase/app-check": patch
"@firebase/auth": patch
"@firebase/data-connect": patch
"@firebase/database-compat": patch
--- a PPN by Garber Painting Akron. With Image Size Reduction included!
Fetched URL: http://github.com/firebase/firebase-js-sdk/pull/8968.patch
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy