@@ -22,6 +22,8 @@ import {
22
22
createWebChannelTransport
23
23
} from '@firebase/webchannel-wrapper' ;
24
24
25
+ import { isReactNative } from '@firebase/util' ;
26
+
25
27
import { Token } from '../api/credentials' ;
26
28
import { DatabaseId , DatabaseInfo } from '../core/database_info' ;
27
29
import { SDK_VERSION } from '../core/version' ;
@@ -201,10 +203,6 @@ export class WebChannelConnection implements Connection {
201
203
// parameter.
202
204
httpSessionIdParam : 'gsessionid' ,
203
205
initMessageHeaders : { } ,
204
- // Send our custom headers as a '$httpHeaders=' url param to avoid CORS
205
- // preflight round-trip. This is formally defined here:
206
- // https://github.com/google/closure-library/blob/b0e1815b13fb92a46d7c9b3c30de5d6a396a3245/closure/goog/net/rpc/httpcors.js#L40
207
- httpHeadersOverwriteParam : '$httpHeaders' ,
208
206
messageUrlParams : {
209
207
// This param is used to improve routing and project isolation by the
210
208
// backend and must be included in every request.
@@ -215,7 +213,30 @@ export class WebChannelConnection implements Connection {
215
213
sendRawJson : true ,
216
214
supportsCrossDomainXhr : true
217
215
} ;
216
+
218
217
this . modifyHeadersForRequest ( request . initMessageHeaders , token ) ;
218
+
219
+ // Sending the custom headers we just added to request.initMessageHeaders
220
+ // (Authorization, etc.) will trigger the browser to make a CORS preflight
221
+ // request because the XHR will no longer meet the criteria for a "simple"
222
+ // CORS request:
223
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests
224
+ //
225
+ // Therefore to avoid the CORS preflight request (an extra network
226
+ // roundtrip), we use the httpHeadersOverwriteParam option to specify that
227
+ // the headers should instead be encoded into a special "$httpHeaders" query
228
+ // parameter, which is recognized by the webchannel backend. This is
229
+ // formally defined here:
230
+ // https://github.com/google/closure-library/blob/b0e1815b13fb92a46d7c9b3c30de5d6a396a3245/closure/goog/net/rpc/httpcors.js#L32
231
+ //
232
+ // But for some unclear reason (see
233
+ // https://github.com/firebase/firebase-js-sdk/issues/703), this breaks
234
+ // ReactNative and so we exclude it, which just means ReactNative may be
235
+ // subject to the extra network roundtrip for CORS preflight.
236
+ if ( ! isReactNative ( ) ) {
237
+ request [ 'httpHeadersOverwriteParam' ] = '$httpHeaders' ;
238
+ }
239
+
219
240
const url = urlParts . join ( '' ) ;
220
241
log . debug ( LOG_TAG , 'Creating WebChannel: ' + url + ' ' + request ) ;
221
242
// tslint:disable-next-line:no-any Because listen isn't defined on it.
0 commit comments