Skip to content

Commit dd54e24

Browse files
Compat Layer for Firestore
1 parent 8922f54 commit dd54e24

File tree

8 files changed

+274
-345
lines changed

8 files changed

+274
-345
lines changed

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

+53-10
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ import { Deferred } from '../../../src/util/promise';
4444
import { LRU_MINIMUM_CACHE_SIZE_BYTES } from '../../../src/local/lru_garbage_collector';
4545
import {
4646
CACHE_SIZE_UNLIMITED,
47-
configureFirestore,
48-
ensureFirestoreConfigured,
49-
FirestoreCompat
47+
FirestoreDatabase
5048
} from '../../../src/api/database';
5149
import {
5250
indexedDbClearPersistence,
5351
indexedDbStoragePrefix
5452
} from '../../../src/local/indexeddb_persistence';
5553
import { PersistenceSettings } from '../../../exp-types';
54+
import { debugAssert } from '../../../src/util/assert';
55+
import { DatabaseInfo } from '../../../src/core/database_info';
5656

5757
/** DOMException error code constants. */
5858
const DOM_EXCEPTION_INVALID_STATE = 11;
@@ -70,18 +70,18 @@ export interface Settings extends LiteSettings {
7070
*/
7171
export class FirebaseFirestore
7272
extends LiteFirestore
73-
implements _FirebaseService, FirestoreCompat {
73+
implements _FirebaseService {
7474
readonly _queue = new AsyncQueue();
7575
readonly _persistenceKey: string;
7676

7777
_firestoreClient: FirestoreClient | undefined;
7878

7979
constructor(
80-
app: FirebaseApp,
80+
app: FirestoreDatabase | FirebaseApp,
8181
authProvider: Provider<FirebaseAuthInternalName>
8282
) {
8383
super(app, authProvider);
84-
this._persistenceKey = app.name;
84+
this._persistenceKey = 'name' in app ? app.name : '[DEFAULT]';
8585
}
8686

8787
_terminate(): Promise<void> {
@@ -94,6 +94,39 @@ export class FirebaseFirestore
9494
}
9595
}
9696

97+
export function ensureFirestoreConfigured(
98+
firestore: FirebaseFirestore
99+
): FirestoreClient {
100+
if (!firestore._firestoreClient) {
101+
configureFirestore(firestore);
102+
}
103+
firestore._firestoreClient!.verifyNotTerminated();
104+
return firestore._firestoreClient as FirestoreClient;
105+
}
106+
107+
export function configureFirestore(firestore: FirebaseFirestore): void {
108+
const settings = firestore._getSettings();
109+
debugAssert(!!settings.host, 'FirestoreSettings.host is not set');
110+
debugAssert(
111+
!firestore._firestoreClient,
112+
'configureFirestore() called multiple times'
113+
);
114+
115+
const databaseInfo = new DatabaseInfo(
116+
firestore._databaseId,
117+
firestore._persistenceKey,
118+
settings.host,
119+
settings.ssl,
120+
settings.experimentalForceLongPolling,
121+
settings.experimentalAutoDetectLongPolling
122+
);
123+
firestore._firestoreClient = new FirestoreClient(
124+
firestore._credentials,
125+
firestore._queue,
126+
databaseInfo
127+
);
128+
}
129+
97130
/**
98131
* Initializes a new instance of Cloud Firestore with the provided settings.
99132
* Can only be called before any other function, including
@@ -129,6 +162,16 @@ export function initializeFirestore(
129162
return firestore;
130163
}
131164

165+
export function initializeStandalone(
166+
database: FirestoreDatabase,
167+
authProvider: Provider<FirebaseAuthInternalName>,
168+
settings: Settings
169+
): FirebaseFirestore {
170+
const firestore = new FirebaseFirestore(database, authProvider);
171+
firestore._setSettings(settings);
172+
return firestore;
173+
}
174+
132175
/**
133176
* Returns the existing instance of Firestore that is associated with the
134177
* provided {@link FirebaseApp}. If no instance exists, initializes a new
@@ -165,7 +208,7 @@ export function getFirestore(app: FirebaseApp): FirebaseFirestore {
165208
* @return A promise that represents successfully enabling persistent storage.
166209
*/
167210
export function enableIndexedDbPersistence(
168-
firestore: FirestoreCompat,
211+
firestore: FirebaseFirestore,
169212
persistenceSettings?: PersistenceSettings
170213
): Promise<void> {
171214
verifyNotInitialized(firestore);
@@ -209,7 +252,7 @@ export function enableIndexedDbPersistence(
209252
* storage.
210253
*/
211254
export function enableMultiTabIndexedDbPersistence(
212-
firestore: FirestoreCompat
255+
firestore: FirebaseFirestore
213256
): Promise<void> {
214257
verifyNotInitialized(firestore);
215258

@@ -322,7 +365,7 @@ function canFallbackFromIndexedDbError(
322365
* cleared. Otherwise, the promise is rejected with an error.
323366
*/
324367
export function clearIndexedDbPersistence(
325-
firestore: FirestoreCompat
368+
firestore: FirebaseFirestore
326369
): Promise<void> {
327370
if (firestore._initialized && !firestore._terminated) {
328371
throw new FirestoreError(
@@ -420,7 +463,7 @@ export function terminate(firestore: FirebaseFirestore): Promise<void> {
420463
return firestore._delete();
421464
}
422465

423-
function verifyNotInitialized(firestore: FirestoreCompat): void {
466+
function verifyNotInitialized(firestore: FirebaseFirestore): void {
424467
if (firestore._initialized || firestore._terminated) {
425468
throw new FirestoreError(
426469
Code.FAILED_PRECONDITION,

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* limitations under the License.
1616
*/
1717

18-
import { FirebaseFirestore } from './database';
18+
import { ensureFirestoreConfigured, FirebaseFirestore } from './database';
1919
import {
2020
_DocumentKeyReference,
2121
ParsedUpdateData,

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { Transaction as LiteTransaction } from '../../../lite/src/api/transactio
1919
import { DocumentSnapshot } from './snapshot';
2020
import { TransactionRunner } from '../../../src/core/transaction_runner';
2121
import { AsyncQueue } from '../../../src/util/async_queue';
22-
import { FirebaseFirestore } from './database';
22+
import { ensureFirestoreConfigured, FirebaseFirestore } from './database';
2323
import { Deferred } from '../../../src/util/promise';
2424
import {
2525
ensureFirestoreConfigured,

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*/
1717

1818
import { WriteBatch } from '../../../lite/src/api/write_batch';
19-
import { FirebaseFirestore } from './database';
19+
import { ensureFirestoreConfigured, FirebaseFirestore } from './database';
2020
import { executeWrite } from './reference';
2121
import { ensureFirestoreConfigured } from '../../../src/api/database';
2222

packages/firestore/exp/test/shim.ts

+10-90
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ import {
7070
validateSetOptions
7171
} from '../../src/util/input_validation';
7272
import { Compat } from '../../src/compat/compat';
73+
import { Firestore } from '../../src/api/database';
7374

7475
export { GeoPoint, Timestamp } from '../index';
7576
export { FieldValue } from '../../src/compat/field_value';
@@ -93,92 +94,11 @@ export class FirebaseApp
9394
}
9495
}
9596

96-
export class FirebaseFirestore
97-
extends Compat<exp.FirebaseFirestore>
98-
implements legacy.FirebaseFirestore {
99-
app = new FirebaseApp(this._delegate.app);
100-
101-
settings(settings: legacy.Settings): void {
102-
initializeFirestore(this.app._delegate, settings);
103-
}
104-
105-
useEmulator(host: string, port: number): void {
106-
this.settings({ host: `${host}:${port}`, ssl: false, merge: true });
107-
}
108-
109-
enablePersistence(settings?: legacy.PersistenceSettings): Promise<void> {
110-
return settings?.synchronizeTabs
111-
? enableMultiTabIndexedDbPersistence(this._delegate)
112-
: enableIndexedDbPersistence(this._delegate);
113-
}
114-
115-
collection(collectionPath: string): CollectionReference<legacy.DocumentData> {
116-
return new CollectionReference(
117-
this,
118-
collection(this._delegate, collectionPath)
119-
);
120-
}
121-
122-
doc(documentPath: string): DocumentReference<legacy.DocumentData> {
123-
return new DocumentReference(this, doc(this._delegate, documentPath));
124-
}
125-
126-
collectionGroup(collectionId: string): Query<legacy.DocumentData> {
127-
return new Query(this, collectionGroup(this._delegate, collectionId));
128-
}
129-
130-
runTransaction<T>(
131-
updateFunction: (transaction: legacy.Transaction) => Promise<T>
132-
): Promise<T> {
133-
return runTransaction(this._delegate, t =>
134-
updateFunction(new Transaction(this, t))
135-
);
136-
}
137-
138-
batch(): legacy.WriteBatch {
139-
return new WriteBatch(writeBatch(this._delegate));
140-
}
141-
142-
clearPersistence(): Promise<void> {
143-
return clearIndexedDbPersistence(this._delegate);
144-
}
145-
146-
enableNetwork(): Promise<void> {
147-
return enableNetwork(this._delegate);
148-
}
149-
150-
disableNetwork(): Promise<void> {
151-
return disableNetwork(this._delegate);
152-
}
153-
154-
waitForPendingWrites(): Promise<void> {
155-
return waitForPendingWrites(this._delegate);
156-
}
157-
158-
onSnapshotsInSync(observer: {
159-
next?: (value: void) => void;
160-
error?: (error: legacy.FirestoreError) => void;
161-
complete?: () => void;
162-
}): () => void;
163-
onSnapshotsInSync(onSync: () => void): () => void;
164-
onSnapshotsInSync(arg: any): () => void {
165-
return onSnapshotsInSync(this._delegate, arg);
166-
}
167-
168-
terminate(): Promise<void> {
169-
return terminate(this._delegate);
170-
}
171-
172-
INTERNAL = {
173-
delete: () => terminate(this._delegate)
174-
};
175-
}
176-
17797
export class Transaction
17898
extends Compat<exp.Transaction>
17999
implements legacy.Transaction {
180100
constructor(
181-
private readonly _firestore: FirebaseFirestore,
101+
private readonly _firestore: Firestore,
182102
delegate: exp.Transaction
183103
) {
184104
super(delegate);
@@ -301,7 +221,7 @@ export class DocumentReference<T = legacy.DocumentData>
301221
extends Compat<exp.DocumentReference<T>>
302222
implements legacy.DocumentReference<T> {
303223
constructor(
304-
readonly firestore: FirebaseFirestore,
224+
readonly firestore: Firestore,
305225
delegate: exp.DocumentReference<T>
306226
) {
307227
super(delegate);
@@ -424,7 +344,7 @@ export class DocumentSnapshot<T = legacy.DocumentData>
424344
extends Compat<exp.DocumentSnapshot<T>>
425345
implements legacy.DocumentSnapshot<T> {
426346
constructor(
427-
private readonly _firestore: FirebaseFirestore,
347+
private readonly _firestore: Firestore,
428348
delegate: exp.DocumentSnapshot<T>
429349
) {
430350
super(delegate);
@@ -455,7 +375,7 @@ export class QueryDocumentSnapshot<T = legacy.DocumentData>
455375
extends DocumentSnapshot<T>
456376
implements legacy.QueryDocumentSnapshot<T> {
457377
constructor(
458-
firestore: FirebaseFirestore,
378+
firestore: Firestore,
459379
readonly _delegate: exp.QueryDocumentSnapshot<T>
460380
) {
461381
super(firestore, _delegate);
@@ -469,7 +389,7 @@ export class QueryDocumentSnapshot<T = legacy.DocumentData>
469389
export class Query<T = legacy.DocumentData>
470390
extends Compat<exp.Query<T>>
471391
implements legacy.Query<T> {
472-
constructor(readonly firestore: FirebaseFirestore, delegate: exp.Query<T>) {
392+
constructor(readonly firestore: Firestore, delegate: exp.Query<T>) {
473393
super(delegate);
474394
}
475395

@@ -592,7 +512,7 @@ export class Query<T = legacy.DocumentData>
592512
export class QuerySnapshot<T = legacy.DocumentData>
593513
implements legacy.QuerySnapshot<T> {
594514
constructor(
595-
readonly _firestore: FirebaseFirestore,
515+
readonly _firestore: Firestore,
596516
readonly _delegate: exp.QuerySnapshot<T>
597517
) {}
598518

@@ -633,7 +553,7 @@ export class QuerySnapshot<T = legacy.DocumentData>
633553
export class DocumentChange<T = legacy.DocumentData>
634554
implements legacy.DocumentChange<T> {
635555
constructor(
636-
private readonly _firestore: FirebaseFirestore,
556+
private readonly _firestore: Firestore,
637557
private readonly _delegate: exp.DocumentChange<T>
638558
) {}
639559
readonly type = this._delegate.type;
@@ -649,7 +569,7 @@ export class CollectionReference<T = legacy.DocumentData>
649569
extends Query<T>
650570
implements legacy.CollectionReference<T> {
651571
constructor(
652-
firestore: FirebaseFirestore,
572+
firestore: Firestore,
653573
readonly _delegate: exp.CollectionReference<T>
654574
) {
655575
super(firestore, _delegate);
@@ -755,7 +675,7 @@ function wrap(value: any): any {
755675
// TODO(mrschmidt): Ideally, we should use an existing instance of
756676
// FirebaseFirestore here rather than instantiating a new instance
757677
return new DocumentReference(
758-
new FirebaseFirestore(value.firestore as exp.FirebaseFirestore),
678+
new Firestore(value.firestore as exp.FirebaseFirestore),
759679
value
760680
);
761681
} else if (isPlainObject(value)) {

0 commit comments

Comments
 (0)