Skip to content

Commit a669ee5

Browse files
authored
Add "experimentalForceLongPolling" option. (#1662)
1 parent d4eb7e4 commit a669ee5

File tree

11 files changed

+77
-9
lines changed

11 files changed

+77
-9
lines changed

packages/firebase/index.d.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5857,6 +5857,24 @@ declare namespace firebase.firestore {
58575857
* CACHE_SIZE_UNLIMITED to disable garbage collection.
58585858
*/
58595859
cacheSizeBytes?: number;
5860+
5861+
/**
5862+
* Forces the SDK’s underlying network transport (WebChannel) to use
5863+
* long-polling. Each response from the backend will be closed immediately
5864+
* after the backend sends data (by default responses are kept open in
5865+
* case the backend has more data to send). This avoids incompatibility
5866+
* issues with certain proxies, antivirus software, etc. that incorrectly
5867+
* buffer traffic indefinitely. Use of this option will cause some
5868+
* performance degradation though.
5869+
*
5870+
* This setting may be removed in a future release. If you find yourself
5871+
* using it to work around a specific network reliability issue, please
5872+
* tell us about it in
5873+
* https://github.com/firebase/firebase-js-sdk/issues/1674.
5874+
*
5875+
* @webonly
5876+
*/
5877+
experimentalForceLongPolling?: boolean;
58605878
}
58615879

58625880
/**

packages/firestore-types/index.d.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,23 @@ export interface Settings {
7676
* CACHE_SIZE_UNLIMITED to disable garbage collection.
7777
*/
7878
cacheSizeBytes?: number;
79+
80+
/**
81+
* Forces the SDK’s underlying network transport (WebChannel) to use
82+
* long-polling. Each response from the backend will be closed immediately
83+
* after the backend sends data (by default responses are kept open in case
84+
* the backend has more data to send). This avoids incompatibility issues
85+
* with certain proxies, antivirus software, etc. that incorrectly buffer
86+
* traffic indefinitely. Use of this option will cause some performance
87+
* degradation though.
88+
*
89+
* This setting may be removed in a future release. If you find yourself
90+
* using it to work around a specific network reliability issue, please tell
91+
* us about it in https://github.com/firebase/firebase-js-sdk/issues/1674.
92+
*
93+
* @webonly
94+
*/
95+
experimentalForceLongPolling?: boolean;
7996
}
8097

8198
/**

packages/firestore/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
# Unreleased
2+
- [feature] Added an `experimentalForceLongPolling` setting that that can be
3+
used to work around proxies that prevent the Firestore client from connecting
4+
to the Firestore backend.
25

36
# 1.1.1
47
- [changed] Increased a connection timeout that could lead to large writes

packages/firestore/src/api/database.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ import {
110110
const DEFAULT_HOST = 'firestore.googleapis.com';
111111
const DEFAULT_SSL = true;
112112
const DEFAULT_TIMESTAMPS_IN_SNAPSHOTS = true;
113+
const DEFAULT_FORCE_LONG_POLLING = false;
113114

114115
/**
115116
* Constant used to indicate the LRU garbage collection should be disabled.
@@ -152,6 +153,8 @@ class FirestoreSettings {
152153

153154
readonly cacheSizeBytes: number;
154155

156+
readonly forceLongPolling: boolean;
157+
155158
// Can be a google-auth-library or gapi client.
156159
// tslint:disable-next-line:no-any
157160
credentials?: any;
@@ -178,7 +181,8 @@ class FirestoreSettings {
178181
'ssl',
179182
'credentials',
180183
'timestampsInSnapshots',
181-
'cacheSizeBytes'
184+
'cacheSizeBytes',
185+
'experimentalForceLongPolling'
182186
]);
183187

184188
validateNamedOptionalType(
@@ -254,6 +258,17 @@ class FirestoreSettings {
254258
this.cacheSizeBytes = settings.cacheSizeBytes;
255259
}
256260
}
261+
262+
validateNamedOptionalType(
263+
'settings',
264+
'boolean',
265+
'experimentalForceLongPolling',
266+
settings.experimentalForceLongPolling
267+
);
268+
this.forceLongPolling =
269+
settings.experimentalForceLongPolling === undefined
270+
? DEFAULT_FORCE_LONG_POLLING
271+
: settings.experimentalForceLongPolling;
257272
}
258273

259274
isEqual(other: FirestoreSettings): boolean {
@@ -262,7 +277,8 @@ class FirestoreSettings {
262277
this.ssl === other.ssl &&
263278
this.timestampsInSnapshots === other.timestampsInSnapshots &&
264279
this.credentials === other.credentials &&
265-
this.cacheSizeBytes === other.cacheSizeBytes
280+
this.cacheSizeBytes === other.cacheSizeBytes &&
281+
this.forceLongPolling === other.forceLongPolling
266282
);
267283
}
268284
}
@@ -413,7 +429,8 @@ export class Firestore implements firestore.FirebaseFirestore, FirebaseService {
413429
this._config.databaseId,
414430
this._config.persistenceKey,
415431
this._config.settings.host,
416-
this._config.settings.ssl
432+
this._config.settings.ssl,
433+
this._config.settings.forceLongPolling
417434
);
418435

419436
const preConverter = (value: unknown) => {

packages/firestore/src/core/database_info.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,15 @@ export class DatabaseInfo {
2727
* storage (used in conjunction with the databaseId).
2828
* @param host The Firestore backend host to connect to.
2929
* @param ssl Whether to use SSL when connecting.
30+
* @param forceLongPolling Whether to use the forceLongPolling option
31+
* when using WebChannel as the network transport.
3032
*/
3133
constructor(
3234
readonly databaseId: DatabaseId,
3335
readonly persistenceKey: string,
3436
readonly host: string,
35-
readonly ssl: boolean
37+
readonly ssl: boolean,
38+
readonly forceLongPolling: boolean
3639
) {}
3740
}
3841

packages/firestore/src/platform_browser/webchannel_connection.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,13 @@ const XHR_TIMEOUT_SECS = 15;
6161
export class WebChannelConnection implements Connection {
6262
private readonly databaseId: DatabaseId;
6363
private readonly baseUrl: string;
64+
private readonly forceLongPolling: boolean;
6465

6566
constructor(info: DatabaseInfo) {
6667
this.databaseId = info.databaseId;
6768
const proto = info.ssl ? 'https' : 'http';
6869
this.baseUrl = proto + '://' + info.host;
70+
this.forceLongPolling = info.forceLongPolling;
6971
}
7072

7173
/**
@@ -217,7 +219,8 @@ export class WebChannelConnection implements Connection {
217219
// set it very large (5-10 minutes) and rely on the browser's builtin
218220
// timeouts to kick in if the request isn't working.
219221
forwardChannelRequestTimeoutMs: 10 * 60 * 1000
220-
}
222+
},
223+
forceLongPolling: this.forceLongPolling
221224
};
222225

223226
this.modifyHeadersForRequest(request.initMessageHeaders, token);

packages/firestore/test/integration/browser/webchannel.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ describeFn('WebChannel', () => {
3535
new DatabaseId('testproject'),
3636
'persistenceKey',
3737
'example.com',
38-
false
38+
/*ssl=*/ false,
39+
/*forceLongPolling=*/ false
3940
);
4041
const conn = new WebChannelConnection(info);
4142
const makeUrl = conn.makeUrl.bind(conn);

packages/firestore/test/integration/util/internal_helpers.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ export function getDefaultDatabaseInfo(): DatabaseInfo {
3939
new DatabaseId(DEFAULT_PROJECT_ID),
4040
'persistenceKey',
4141
DEFAULT_SETTINGS.host!,
42-
!!DEFAULT_SETTINGS.ssl
42+
!!DEFAULT_SETTINGS.ssl,
43+
!!DEFAULT_SETTINGS.experimentalForceLongPolling
4344
);
4445
}
4546

packages/firestore/test/unit/local/persistence_test_helpers.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ const TEST_DATABASE_INFO = new DatabaseInfo(
6060
TEST_DATABASE_ID,
6161
'[PersistenceTestHelpers]',
6262
'host',
63-
/*ssl=*/ false
63+
/*ssl=*/ false,
64+
/*forceLongPolling=*/ false
6465
);
6566

6667
/** The persistence prefix used for testing in IndexedBD and LocalStorage. */

packages/firestore/test/unit/specs/spec_test_runner.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,8 @@ abstract class TestRunner {
401401
new DatabaseId('project'),
402402
'persistenceKey',
403403
'host',
404-
false
404+
/*ssl=*/ false,
405+
/*forceLongPolling=*/ false
405406
);
406407

407408
// TODO(mrschmidt): During client startup in `firestore_client`, we block

packages/webchannel-wrapper/externs/overrides.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,6 @@ goog.net.WebChannel.Options.fastHandshake;
6565

6666
/** @type {!Object<string, boolean|number>|undefined} */
6767
goog.net.WebChannel.Options.internalChannelParams;
68+
69+
/** @type {boolean|undefined} */
70+
goog.net.WebChannel.Options.forceLongPolling;

0 commit comments

Comments
 (0)