Skip to content

Commit d1670fe

Browse files
committed
sync head
2 parents 8aedf92 + 417dd7c commit d1670fe

26 files changed

+277
-78
lines changed

.changeset/config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"changelog": ["@changesets/changelog-github", { "repo": "firebase/firebase-js-sdk"}],
44
"commit": false,
55
"linked": [],
6-
"access": "restricted",
6+
"access": "public",
77
"baseBranch": "master",
88
"updateInternalDependencies": "patch",
99
"ignore": [

.changeset/gorgeous-beers-build.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
---

.changeset/nasty-pigs-invite.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@firebase/functions": patch
3+
"firebase": patch
4+
---
5+
6+
Clear timeout after a successful response or after the request is canceled. Fixes [issue 3289](https://github.com/firebase/firebase-js-sdk/issues/3289).

.changeset/perfect-terms-press.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
---
2+
3+
---

.changeset/strong-geckos-peel.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
---

.changeset/thick-rabbits-guess.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"firebase": patch
3+
"@firebase/firestore": patch
4+
---
5+
6+
[fixed] Removed a delay that may have prevented Firestore from immediately
7+
reestablishing a network connection if a connectivity change occurred while
8+
the app was in the background.

config/functions/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
},
99
"private": true,
1010
"engines": {
11-
"node": "8"
11+
"node": "10"
1212
}
1313
}

packages/firestore/exp/index.node.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export {
5454
parent
5555
} from '../lite/src/api/reference';
5656

57-
export { runTransaction, Transaction } from '../lite/src/api/transaction';
57+
export { runTransaction, Transaction } from './src/api/transaction';
5858

5959
export {
6060
getDoc,

packages/firestore/exp/src/api/database.ts

Lines changed: 65 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,18 @@ import {
3333
MemoryComponentProvider
3434
} from '../../../src/core/component_provider';
3535

36-
import { Firestore as LiteFirestore } from '../../../lite/src/api/database';
36+
import {
37+
DEFAULT_FORCE_LONG_POLLING,
38+
DEFAULT_HOST,
39+
DEFAULT_SSL,
40+
Firestore as LiteFirestore
41+
} from '../../../lite/src/api/database';
3742
import { cast } from '../../../lite/src/api/util';
3843
import { Code, FirestoreError } from '../../../src/util/error';
3944
import { Deferred } from '../../../src/util/promise';
4045
import { LruParams } from '../../../src/local/lru_garbage_collector';
46+
import { CACHE_SIZE_UNLIMITED } from '../../../src/api/database';
47+
import { DatabaseInfo } from '../../../src/core/database_info';
4148

4249
/**
4350
* The root reference to the Firestore database and the entry point for the
@@ -46,25 +53,27 @@ import { LruParams } from '../../../src/local/lru_garbage_collector';
4653
export class Firestore extends LiteFirestore
4754
implements firestore.FirebaseFirestore, _FirebaseService {
4855
private readonly _queue = new AsyncQueue();
56+
private readonly _firestoreClient: FirestoreClient;
4957
private readonly _persistenceKey: string;
5058
private _componentProvider: ComponentProvider = new MemoryComponentProvider();
5159

5260
// Assigned via _getFirestoreClient()
53-
private _firestoreClientPromise?: Promise<FirestoreClient>;
61+
private _deferredInitialization?: Promise<void>;
5462

5563
protected _persistenceSettings: PersistenceSettings = { durable: false };
5664
// We override the Settings property of the Lite SDK since the full Firestore
5765
// SDK supports more settings.
5866
protected _settings?: firestore.Settings;
5967

60-
_terminated: boolean = false;
68+
private _terminated: boolean = false;
6169

6270
constructor(
6371
app: FirebaseApp,
6472
authProvider: Provider<FirebaseAuthInternalName>
6573
) {
6674
super(app, authProvider);
6775
this._persistenceKey = app.name;
76+
this._firestoreClient = new FirestoreClient(this._credentials, this._queue);
6877
}
6978

7079
_getSettings(): firestore.Settings {
@@ -75,26 +84,29 @@ export class Firestore extends LiteFirestore
7584
}
7685

7786
_getFirestoreClient(): Promise<FirestoreClient> {
78-
if (!this._firestoreClientPromise) {
87+
if (this._terminated) {
88+
throw new FirestoreError(
89+
Code.FAILED_PRECONDITION,
90+
'The client has already been terminated.'
91+
);
92+
}
93+
94+
if (!this._deferredInitialization) {
7995
const settings = this._getSettings();
8096
const databaseInfo = this._makeDatabaseInfo(
8197
settings.host,
8298
settings.ssl,
8399
settings.experimentalForceLongPolling
84100
);
85101

86-
const firestoreClient = new FirestoreClient(
102+
this._deferredInitialization = this._firestoreClient.start(
87103
databaseInfo,
88-
this._credentials,
89-
this._queue
104+
this._componentProvider,
105+
this._persistenceSettings
90106
);
91-
92-
this._firestoreClientPromise = firestoreClient
93-
.start(this._componentProvider, this._persistenceSettings)
94-
.then(() => firestoreClient);
95107
}
96108

97-
return this._firestoreClientPromise;
109+
return this._deferredInitialization.then(() => this._firestoreClient);
98110
}
99111

100112
// TODO(firestorexp): Factor out MultiTabComponentProvider and remove
@@ -103,11 +115,11 @@ export class Firestore extends LiteFirestore
103115
persistenceProvider: ComponentProvider,
104116
synchronizeTabs: boolean
105117
): Promise<void> {
106-
if (this._firestoreClientPromise) {
118+
if (this._deferredInitialization) {
107119
throw new FirestoreError(
108120
Code.FAILED_PRECONDITION,
109121
'Firestore has already been started and persistence can no longer ' +
110-
'be enabled. You can only call enable persistence before calling ' +
122+
'be enabled. You can only enable persistence before calling ' +
111123
'any other methods on a Firestore object.'
112124
);
113125
}
@@ -131,10 +143,10 @@ export class Firestore extends LiteFirestore
131143
}
132144

133145
_clearPersistence(): Promise<void> {
134-
if (this._firestoreClientPromise !== undefined && !this._terminated) {
146+
if (this._deferredInitialization !== undefined && !this._terminated) {
135147
throw new FirestoreError(
136148
Code.FAILED_PRECONDITION,
137-
'Persistence can only be cleared before the Firestore instance is ' +
149+
'Persistence can only be cleared before a Firestore instance is ' +
138150
'initialized or after it is terminated.'
139151
);
140152
}
@@ -156,6 +168,30 @@ export class Firestore extends LiteFirestore
156168
});
157169
return deferred.promise;
158170
}
171+
172+
protected _makeDatabaseInfo(
173+
host?: string,
174+
ssl?: boolean,
175+
forceLongPolling?: boolean
176+
): DatabaseInfo {
177+
return new DatabaseInfo(
178+
this._databaseId,
179+
this._persistenceKey,
180+
host ?? DEFAULT_HOST,
181+
ssl ?? DEFAULT_SSL,
182+
forceLongPolling ?? DEFAULT_FORCE_LONG_POLLING
183+
);
184+
}
185+
186+
_terminate(): Promise<void> {
187+
this._terminated = true;
188+
if (this._deferredInitialization) {
189+
return this._deferredInitialization.then(() =>
190+
this._firestoreClient.terminate()
191+
);
192+
}
193+
return Promise.resolve();
194+
}
159195
}
160196

161197
export function initializeFirestore(
@@ -166,6 +202,18 @@ export function initializeFirestore(
166202
app,
167203
'firestore-exp'
168204
).getImmediate() as Firestore;
205+
206+
if (
207+
settings.cacheSizeBytes !== undefined &&
208+
settings.cacheSizeBytes !== CACHE_SIZE_UNLIMITED &&
209+
settings.cacheSizeBytes < LruParams.MINIMUM_CACHE_SIZE_BYTES
210+
) {
211+
throw new FirestoreError(
212+
Code.INVALID_ARGUMENT,
213+
`cacheSizeBytes must be at least ${LruParams.MINIMUM_CACHE_SIZE_BYTES}`
214+
);
215+
}
216+
169217
firestore._configureClient(settings);
170218
return firestore;
171219
}
@@ -233,8 +281,5 @@ export function terminate(
233281
): Promise<void> {
234282
_removeServiceInstance(firestore.app, 'firestore/lite');
235283
const firestoreImpl = cast(firestore, Firestore);
236-
firestoreImpl._terminated = true;
237-
return firestoreImpl
238-
._getFirestoreClient()
239-
.then(firestoreClient => firestoreClient.terminate());
284+
return firestoreImpl._terminate();
240285
}

packages/firestore/exp/src/api/reference.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ import {
5050
} from '../../../lite/src/api/reference';
5151
import { Document } from '../../../src/model/document';
5252
import { DeleteMutation, Precondition } from '../../../src/model/mutation';
53-
import { FieldPath } from '../../../src/api/field_path';
53+
import { FieldPath } from '../../../lite/src/api/field_path';
5454
import {
5555
CompleteFn,
5656
ErrorFn,
@@ -262,7 +262,7 @@ export function addDoc<T>(
262262
data: T
263263
): Promise<firestore.DocumentReference<T>> {
264264
const collRef = cast<CollectionReference<T>>(reference, CollectionReference);
265-
const firestore = cast(collRef, Firestore);
265+
const firestore = cast(collRef.firestore, Firestore);
266266
const docRef = doc(collRef);
267267

268268
const convertedValue = applyFirestoreDataConverter(collRef._converter, data);
@@ -404,7 +404,7 @@ export function onSnapshot<T>(
404404
);
405405
} else {
406406
const query = cast<Query<T>>(ref, Query);
407-
const firestore = cast(query, Firestore);
407+
const firestore = cast(query.firestore, Firestore);
408408

409409
const observer: PartialObserver<ViewSnapshot> = {
410410
next: snapshot => {

packages/firestore/exp/src/api/snapshot.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export class DocumentSnapshot<T = firestore.DocumentData>
7676
this.metadata,
7777
/* converter= */ null
7878
);
79-
return this._converter.fromFirestore(snapshot);
79+
return this._converter.fromFirestore(snapshot, options);
8080
} else {
8181
const userDataWriter = new UserDataWriter(
8282
this._firestoreImpl._databaseId,
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import * as firestore from '../../index';
19+
20+
import { Transaction as LiteTransaction } from '../../../lite/src/api/transaction';
21+
import { DocumentSnapshot } from './snapshot';
22+
import { TransactionRunner } from '../../../src/core/transaction_runner';
23+
import { AsyncQueue } from '../../../src/util/async_queue';
24+
import { cast } from '../../../lite/src/api/util';
25+
import { Firestore } from './database';
26+
import { Deferred } from '../../../src/util/promise';
27+
import { SnapshotMetadata } from '../../../src/api/database';
28+
import { Transaction as InternalTransaction } from '../../../src/core/transaction';
29+
import { validateReference } from '../../../lite/src/api/write_batch';
30+
31+
export class Transaction extends LiteTransaction
32+
implements firestore.Transaction {
33+
// This class implements the same logic as the Transaction API in the Lite SDK
34+
// but is subclassed in order to return its own DocumentSnapshot types.
35+
36+
constructor(
37+
protected readonly _firestore: Firestore,
38+
_transaction: InternalTransaction
39+
) {
40+
super(_firestore, _transaction);
41+
}
42+
43+
get<T>(
44+
documentRef: firestore.DocumentReference<T>
45+
): Promise<DocumentSnapshot<T>> {
46+
const ref = validateReference<T>(documentRef, this._firestore);
47+
return super
48+
.get(documentRef)
49+
.then(
50+
liteDocumentSnapshot =>
51+
new DocumentSnapshot(
52+
this._firestore,
53+
ref._key,
54+
liteDocumentSnapshot._document,
55+
new SnapshotMetadata(
56+
/* hasPendingWrites= */ false,
57+
/* fromCache= */ false
58+
),
59+
ref._converter
60+
)
61+
);
62+
}
63+
}
64+
65+
export function runTransaction<T>(
66+
firestore: firestore.FirebaseFirestore,
67+
updateFunction: (transaction: firestore.Transaction) => Promise<T>
68+
): Promise<T> {
69+
const firestoreClient = cast(firestore, Firestore);
70+
return firestoreClient._getDatastore().then(async datastore => {
71+
const deferred = new Deferred<T>();
72+
new TransactionRunner<T>(
73+
new AsyncQueue(),
74+
datastore,
75+
internalTransaction =>
76+
updateFunction(new Transaction(firestoreClient, internalTransaction)),
77+
deferred
78+
).run();
79+
return deferred.promise;
80+
});
81+
}

packages/firestore/lite/src/api/database.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ import { cast } from './util';
3939
import { Settings } from '../../';
4040

4141
// settings() defaults:
42-
const DEFAULT_HOST = 'firestore.googleapis.com';
43-
const DEFAULT_SSL = true;
44-
const DEFAULT_FORCE_LONG_POLLING = false; // Used by full SDK
42+
export const DEFAULT_HOST = 'firestore.googleapis.com';
43+
export const DEFAULT_SSL = true;
44+
export const DEFAULT_FORCE_LONG_POLLING = false; // Used by full SDK
4545

4646
/**
4747
* The root reference to the Firestore Lite database.
@@ -101,17 +101,13 @@ export class Firestore
101101
return this._datastorePromise;
102102
}
103103

104-
protected _makeDatabaseInfo(
105-
host?: string,
106-
ssl?: boolean,
107-
forceLongPolling?: boolean
108-
): DatabaseInfo {
104+
protected _makeDatabaseInfo(host?: string, ssl?: boolean): DatabaseInfo {
109105
return new DatabaseInfo(
110106
this._databaseId,
111107
/* persistenceKey= */ 'unsupported',
112108
host ?? DEFAULT_HOST,
113109
ssl ?? DEFAULT_SSL,
114-
forceLongPolling ?? DEFAULT_FORCE_LONG_POLLING
110+
DEFAULT_FORCE_LONG_POLLING
115111
);
116112
}
117113

packages/firestore/lite/src/api/field_value.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class FieldValueDelegate extends FieldValue implements firestore.FieldValue {
6363
}
6464

6565
export function deleteField(): firestore.FieldValue {
66-
return new FieldValueDelegate(new DeleteFieldValueImpl('delete'));
66+
return new FieldValueDelegate(new DeleteFieldValueImpl('deleteField'));
6767
}
6868

6969
export function serverTimestamp(): firestore.FieldValue {

packages/firestore/lite/src/api/reference.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ export function collection(
291291
parent: firestore.FirebaseFirestore | firestore.DocumentReference<unknown>,
292292
relativePath: string
293293
): CollectionReference<firestore.DocumentData> {
294-
validateArgType('doc', 'non-empty string', 2, relativePath);
294+
validateArgType('collection', 'non-empty string', 2, relativePath);
295295
const path = ResourcePath.fromString(relativePath);
296296
if (parent instanceof Firestore) {
297297
validateCollectionPath(path);

0 commit comments

Comments
 (0)