@@ -85,30 +85,14 @@ export const MAX_CONCURRENT_LIMBO_RESOLUTIONS = 100;
85
85
* async queue that is shared by all of the other components in the system.
86
86
*/
87
87
export class FirestoreClient {
88
- // NOTE: These should technically have '|undefined' in the types, since
89
- // they're initialized asynchronously rather than in the constructor, but
90
- // given that all work is done on the async queue and we assert that
91
- // initialization completes before any other work is queued, we're cheating
92
- // with the types rather than littering the code with '!' or unnecessary
93
- // undefined checks.
94
- private databaseInfo ! : DatabaseInfo ;
95
88
private user = User . UNAUTHENTICATED ;
89
+ private readonly clientId = AutoId . newId ( ) ;
96
90
private credentialListener : CredentialChangeListener = ( ) => { } ;
91
+ private readonly receivedInitialUser = new Deferred < void > ( ) ;
97
92
98
93
offlineComponents ?: OfflineComponentProvider ;
99
94
onlineComponents ?: OnlineComponentProvider ;
100
95
101
- private readonly clientId = AutoId . newId ( ) ;
102
-
103
- // We defer our initialization until we get the current user from
104
- // setChangeListener(). We block the async queue until we got the initial
105
- // user and the initialization is completed. This will prevent any scheduled
106
- // work from happening before initialization is completed.
107
- //
108
- // If initializationDone resolved then the FirestoreClient is in a usable
109
- // state.
110
- private readonly initializationDone = new Deferred < void > ( ) ;
111
-
112
96
constructor (
113
97
private credentials : CredentialsProvider ,
114
98
/**
@@ -119,57 +103,21 @@ export class FirestoreClient {
119
103
* start processing a new operation while the previous one is waiting for
120
104
* an async I/O to complete).
121
105
*/
122
- public asyncQueue : AsyncQueue
123
- ) { }
124
-
125
- /**
126
- * Starts up the FirestoreClient, returning only whether or not enabling
127
- * persistence succeeded.
128
- *
129
- * The intent here is to "do the right thing" as far as users are concerned.
130
- * Namely, in cases where offline persistence is requested and possible,
131
- * enable it, but otherwise fall back to persistence disabled. For the most
132
- * part we expect this to succeed one way or the other so we don't expect our
133
- * users to actually wait on the firestore.enablePersistence Promise since
134
- * they generally won't care.
135
- *
136
- * Of course some users actually do care about whether or not persistence
137
- * was successfully enabled, so the Promise returned from this method
138
- * indicates this outcome.
139
- *
140
- * This presents a problem though: even before enablePersistence resolves or
141
- * rejects, users may have made calls to e.g. firestore.collection() which
142
- * means that the FirestoreClient in there will be available and will be
143
- * enqueuing actions on the async queue.
144
- *
145
- * Meanwhile any failure of an operation on the async queue causes it to
146
- * panic and reject any further work, on the premise that unhandled errors
147
- * are fatal.
148
- *
149
- * Consequently the fallback is handled internally here in start, and if the
150
- * fallback succeeds we signal success to the async queue even though the
151
- * start() itself signals failure.
152
- *
153
- * @param databaseInfo The connection information for the current instance.
154
- */
155
- start ( databaseInfo : DatabaseInfo ) : void {
156
- this . databaseInfo = databaseInfo ;
157
-
106
+ public asyncQueue : AsyncQueue ,
107
+ private databaseInfo : DatabaseInfo
108
+ ) {
158
109
this . credentials . setChangeListener ( user => {
159
110
logDebug ( LOG_TAG , 'Received user=' , user . uid ) ;
160
111
if ( ! this . user . isEqual ( user ) ) {
161
112
this . user = user ;
162
113
this . credentialListener ( user ) ;
163
114
}
164
- this . initializationDone . resolve ( ) ;
115
+ this . receivedInitialUser . resolve ( ) ;
165
116
} ) ;
166
-
167
- // Block the async queue until initialization is done
168
- this . asyncQueue . enqueueAndForget ( ( ) => this . initializationDone . promise ) ;
169
117
}
170
118
171
119
async getConfiguration ( ) : Promise < ComponentConfiguration > {
172
- await this . initializationDone . promise ;
120
+ await this . receivedInitialUser . promise ;
173
121
174
122
return {
175
123
asyncQueue : this . asyncQueue ,
@@ -184,7 +132,7 @@ export class FirestoreClient {
184
132
setCredentialChangeListener ( listener : ( user : User ) => void ) : void {
185
133
this . credentialListener = listener ;
186
134
// eslint-disable-next-line @typescript-eslint/no-floating-promises
187
- this . initializationDone . promise . then ( ( ) =>
135
+ this . receivedInitialUser . promise . then ( ( ) =>
188
136
this . credentialListener ( this . user )
189
137
) ;
190
138
}
0 commit comments