From 4ce8674de4524c38b47dbf923e06af09174fa5e1 Mon Sep 17 00:00:00 2001 From: James Daniels Date: Thu, 16 Sep 2021 19:49:49 -0400 Subject: [PATCH 1/7] Lots of little things --- samples/advanced/package.json | 1 + .../src/app/messaging/messaging.component.ts | 2 +- samples/advanced/yarn.lock | 24 +-- samples/modular/server.ts | 2 - .../src/app/app-check/app-check.component.ts | 18 +- samples/modular/src/app/app.browser.module.ts | 42 +---- samples/modular/src/app/app.module.ts | 19 ++ samples/modular/src/app/app.server.module.ts | 18 +- .../src/app/messaging/messaging.component.ts | 1 + samples/modular/yarn.lock | 31 ++- src/analytics/analytics.module.ts | 28 +-- src/analytics/public_api.ts | 2 + src/analytics/screen-tracking.service.ts | 176 ++++++++++++++++++ src/analytics/user-tracking.service.ts | 39 ++++ src/app-check/app-check.module.ts | 17 +- src/app/app.module.ts | 15 +- src/auth/auth.module.ts | 16 +- src/compat/analytics/analytics.ts | 3 +- .../analytics/screen-tracking.service.ts | 133 +------------ src/compat/auth/auth.ts | 3 +- src/compat/cache.ts | 34 ++++ src/compat/database/database.ts | 3 +- src/compat/firestore/firestore.ts | 3 +- src/compat/functions/functions.ts | 3 +- src/compat/messaging/messaging.ts | 4 +- src/compat/performance/performance.ts | 3 +- src/compat/public_api.ts | 1 + src/compat/remote-config/remote-config.ts | 3 +- src/compat/storage/storage.ts | 4 +- src/core.ts | 53 +----- src/database/database.module.ts | 13 +- src/firestore/firestore.module.ts | 15 +- src/firestore/lite/lite.module.ts | 13 +- src/functions/functions.module.ts | 13 +- src/messaging/messaging.module.ts | 19 +- src/performance/performance.module.ts | 26 ++- src/remote-config/remote-config.module.ts | 26 ++- src/storage/storage.module.ts | 15 +- 38 files changed, 498 insertions(+), 343 deletions(-) create mode 100644 src/analytics/screen-tracking.service.ts create mode 100644 src/analytics/user-tracking.service.ts create mode 100644 src/compat/cache.ts diff --git a/samples/advanced/package.json b/samples/advanced/package.json index 7cdcb11d7..8746d1ba6 100644 --- a/samples/advanced/package.json +++ b/samples/advanced/package.json @@ -60,6 +60,7 @@ "karma-jasmine": "~4.0.0", "karma-jasmine-html-reporter": "^1.5.0", "ng-packagr": "^12.0.0", + "ts-mixer": "^6.0.0", "ts-node": "~9.1.1", "tslint": "~6.1.3", "typescript": "~4.2.3", diff --git a/samples/advanced/src/app/messaging/messaging.component.ts b/samples/advanced/src/app/messaging/messaging.component.ts index 6e617a809..d89e28c6e 100644 --- a/samples/advanced/src/app/messaging/messaging.component.ts +++ b/samples/advanced/src/app/messaging/messaging.component.ts @@ -22,7 +22,7 @@ export class MessagingComponent implements OnInit { message$: Observable = EMPTY; showRequest = false; - constructor(@Optional() messaging: Messaging) { + constructor(messaging: Messaging) { if (messaging) { this.token$ = from( navigator.serviceWorker.register('firebase-messaging-sw.js', { type: 'module', scope: '__' }). diff --git a/samples/advanced/yarn.lock b/samples/advanced/yarn.lock index c680d5ce9..2534272c6 100644 --- a/samples/advanced/yarn.lock +++ b/samples/advanced/yarn.lock @@ -246,24 +246,7 @@ "@angular/fire@../../angular-fire-7.1.0.tgz": version "7.1.0" - resolved "../../angular-fire-7.1.0.tgz#09c9450ae2d6290d22a9c57ce2246d1c4ded7f10" - dependencies: - file-loader "^6.2.0" - fs-extra "^8.0.1" - fuzzy "^0.1.3" - inquirer "^8.1.1" - inquirer-autocomplete-prompt "^1.0.1" - jsonc-parser "^3.0.0" - node-fetch "^2.6.1" - open "^8.0.0" - ora "^5.3.0" - semver "^7.1.3" - triple-beam "^1.3.0" - tslib "^2.0.0" - winston "^3.0.0" - -"@angular/fire@../../dist/packages-dist": - version "7.1.0" + resolved "../../angular-fire-7.1.0.tgz#749a0443e5974789fbdc5a3b31237aa6506d7b7e" dependencies: file-loader "^6.2.0" fs-extra "^8.0.1" @@ -9983,6 +9966,11 @@ triple-beam@^1.2.0, triple-beam@^1.3.0: resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== +ts-mixer@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/ts-mixer/-/ts-mixer-6.0.0.tgz#4e631d3a36e3fa9521b973b132e8353bc7267f9f" + integrity sha512-nXIb1fvdY5CBSrDIblLn73NW0qRDk5yJ0Sk1qPBF560OdJfQp9jhl+0tzcY09OZ9U+6GpeoI9RjwoIKFIoB9MQ== + ts-node@~9.1.1: version "9.1.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" diff --git a/samples/modular/server.ts b/samples/modular/server.ts index 49524cc64..b97d0e695 100644 --- a/samples/modular/server.ts +++ b/samples/modular/server.ts @@ -10,8 +10,6 @@ import { APP_BASE_HREF } from '@angular/common'; import { existsSync } from 'fs'; // These polyfills are for app-check Node.js -// @ts-ignore -globalThis.self = globalThis; globalThis.fetch = require('node-fetch').default; import '@angular/fire/firestore-protos'; diff --git a/samples/modular/src/app/app-check/app-check.component.ts b/samples/modular/src/app/app-check/app-check.component.ts index 667ef913a..524956555 100644 --- a/samples/modular/src/app/app-check/app-check.component.ts +++ b/samples/modular/src/app/app-check/app-check.component.ts @@ -1,9 +1,9 @@ import { Component, OnInit } from '@angular/core'; import { getToken, AppCheck } from '@angular/fire/app-check'; import { traceUntilFirst } from '@angular/fire/performance'; -import { from, Observable } from 'rxjs'; +import { EMPTY, from, Observable } from 'rxjs'; import { keepUnstableUntilFirst } from '@angular/fire'; -import { share, tap } from 'rxjs/operators'; +import { share } from 'rxjs/operators'; @Component({ selector: 'app-app-check', @@ -20,11 +20,15 @@ export class AppCheckComponent implements OnInit { readonly change$: Observable; constructor(appCheck: AppCheck) { - this.change$ = from(getToken(appCheck)).pipe( - traceUntilFirst('app-check'), - keepUnstableUntilFirst, - share(), - ); + if (appCheck) { + this.change$ = from(getToken(appCheck)).pipe( + traceUntilFirst('app-check'), + keepUnstableUntilFirst, + share(), + ); + } else { + this.change$ = EMPTY; + } } ngOnInit(): void { diff --git a/samples/modular/src/app/app.browser.module.ts b/samples/modular/src/app/app.browser.module.ts index 0cdfd0fd1..9369e4714 100644 --- a/samples/modular/src/app/app.browser.module.ts +++ b/samples/modular/src/app/app.browser.module.ts @@ -1,42 +1,20 @@ import { NgModule } from '@angular/core'; -import { getRemoteConfig, provideRemoteConfig } from '@angular/fire/remote-config'; -import { getAnalytics, provideAnalytics } from '@angular/fire/analytics'; -import { getMessaging, provideMessaging } from '@angular/fire/messaging'; -import { getApp } from '@angular/fire/app'; - import { AppModule } from './app.module'; import { AppComponent } from './app.component'; -import { ServiceWorkerModule } from '@angular/service-worker'; -import { environment } from '../environments/environment'; -import { provideAuth, connectAuthEmulator } from '@angular/fire/auth'; - -import { initializeAuth, browserPopupRedirectResolver, indexedDBLocalPersistence } from '@angular/fire/auth'; -import { provideAppCheck, initializeAppCheck, ReCaptchaV3Provider } from '@angular/fire/app-check'; +import { provideAppCheck, initializeAppCheck, ReCaptchaV3Provider, AppCheckModule } from '@angular/fire/app-check'; +import { environment } from 'src/environments/environment'; @NgModule({ imports: [ AppModule, - provideRemoteConfig(() => getRemoteConfig()), - provideAnalytics(() => getAnalytics()), - provideMessaging(() => getMessaging()), - provideAuth(() => { - const auth = initializeAuth(getApp(), { - persistence: indexedDBLocalPersistence, - popupRedirectResolver: browserPopupRedirectResolver, - }); - if (environment.useEmulators) { - connectAuthEmulator(auth, 'http://localhost:9099', { disableWarnings: true }); - } - return auth; - }), - provideAppCheck(() => { - const provider = new ReCaptchaV3Provider(environment.recaptcha3SiteKey); - return initializeAppCheck(undefined, { provider, isTokenAutoRefreshEnabled: true }); - }), - ServiceWorkerModule.register('ngsw-worker.js', { - enabled: environment.production, - registrationStrategy: 'registerWhenStable:30000' - }), + ...[ + environment.useEmulators ? [AppCheckModule] : [ + provideAppCheck(() => { + const provider = new ReCaptchaV3Provider(environment.recaptcha3SiteKey); + return initializeAppCheck(undefined, { provider, isTokenAutoRefreshEnabled: true }); + }) + ] + ] ], bootstrap: [AppComponent], }) diff --git a/samples/modular/src/app/app.module.ts b/samples/modular/src/app/app.module.ts index e8c4c0b92..de1070047 100644 --- a/samples/modular/src/app/app.module.ts +++ b/samples/modular/src/app/app.module.ts @@ -5,6 +5,11 @@ import { connectFunctionsEmulator, FunctionsModule, getFunctions, provideFunctio import { connectFirestoreEmulator, getFirestore, provideFirestore, enableMultiTabIndexedDbPersistence } from '@angular/fire/firestore'; import { connectDatabaseEmulator, getDatabase, provideDatabase } from '@angular/fire/database'; import { connectStorageEmulator, getStorage, provideStorage } from '@angular/fire/storage'; +import { getRemoteConfig, provideRemoteConfig } from '@angular/fire/remote-config'; +import { getAnalytics, provideAnalytics, ScreenTrackingService, UserTrackingService } from '@angular/fire/analytics'; +import { getMessaging, provideMessaging } from '@angular/fire/messaging'; +import { provideAuth, connectAuthEmulator, getAuth } from '@angular/fire/auth'; +import { ServiceWorkerModule } from '@angular/service-worker'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @@ -44,6 +49,20 @@ export const persistenceEnabled = new Promise(resolve => { BrowserModule.withServerTransition({ appId: 'serverApp' }), AppRoutingModule, FunctionsModule, + provideRemoteConfig(() => getRemoteConfig()), + provideAnalytics(() => getAnalytics()), + provideMessaging(() => getMessaging()), + provideAuth(() => { + const auth = getAuth(); + if (environment.useEmulators) { + connectAuthEmulator(auth, 'http://localhost:9099', { disableWarnings: true }); + } + return auth; + }), + ServiceWorkerModule.register('ngsw-worker.js', { + enabled: environment.production, + registrationStrategy: 'registerWhenStable:30000' + }), provideFirebaseApp(() => initializeApp(environment.firebase)), provideFirestore(() => { const firestore = getFirestore(); diff --git a/samples/modular/src/app/app.server.module.ts b/samples/modular/src/app/app.server.module.ts index 3fbbe2116..d236227bc 100644 --- a/samples/modular/src/app/app.server.module.ts +++ b/samples/modular/src/app/app.server.module.ts @@ -1,17 +1,31 @@ import { NgModule } from '@angular/core'; import { ServerModule } from '@angular/platform-server'; import { provideAppCheck, CustomProvider, initializeAppCheck } from '@angular/fire/app-check'; +import * as admin from 'firebase-admin'; import { AppModule } from './app.module'; import { AppComponent } from './app.component'; +import { environment } from 'src/environments/environment'; + +const firebaseAdminApp = admin.apps[0] || admin.initializeApp( + // In Cloud Functions we can auto-initialize + process.env.FUNCTION_NAME ? undefined : { + credential: admin.credential.applicationDefault(), + databaseURL: environment.firebase.databaseURL, + } +); + +const appCheckToken = firebaseAdminApp.appCheck().createToken(environment.firebase.appId, { + ttlMillis: 604_800_000, // 1 week +}).then(({ token, ttlMillis: expireTimeMillis }) => ({ token, expireTimeMillis } )); @NgModule({ imports: [ AppModule, ServerModule, provideAppCheck(() => { - const provider = new CustomProvider({ getToken: () => Promise.reject() }); - return initializeAppCheck(undefined, { provider, isTokenAutoRefreshEnabled: true }); + const provider = new CustomProvider({ getToken: () => appCheckToken }); + return initializeAppCheck(undefined, { provider, isTokenAutoRefreshEnabled: false }); }), ], bootstrap: [AppComponent], diff --git a/samples/modular/src/app/messaging/messaging.component.ts b/samples/modular/src/app/messaging/messaging.component.ts index 047888c09..d32d7e912 100644 --- a/samples/modular/src/app/messaging/messaging.component.ts +++ b/samples/modular/src/app/messaging/messaging.component.ts @@ -23,6 +23,7 @@ export class MessagingComponent implements OnInit { showRequest = false; constructor(@Optional() messaging: Messaging) { + console.log('messaging', messaging); if (messaging) { this.token$ = from( navigator.serviceWorker.register('firebase-messaging-sw.js', { type: 'module', scope: '__' }). diff --git a/samples/modular/yarn.lock b/samples/modular/yarn.lock index 61accf228..4fa7a44b0 100644 --- a/samples/modular/yarn.lock +++ b/samples/modular/yarn.lock @@ -247,11 +247,16 @@ "@angular/fire@../../dist/packages-dist": version "7.1.0" dependencies: + file-loader "^6.2.0" + fs-extra "^8.0.1" fuzzy "^0.1.3" + inquirer "^8.1.1" inquirer-autocomplete-prompt "^1.0.1" jsonc-parser "^3.0.0" + node-fetch "^2.6.1" open "^8.0.0" ora "^5.3.0" + semver "^7.1.3" triple-beam "^1.3.0" tslib "^2.0.0" winston "^3.0.0" @@ -5668,7 +5673,7 @@ fs-extra@^5.0.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^8.1.0: +fs-extra@^8.0.1, fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== @@ -6523,6 +6528,26 @@ inquirer@^6.2.2: strip-ansi "^5.1.0" through "^2.3.6" +inquirer@^8.1.1: + version "8.1.5" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.1.5.tgz#2dc5159203c826d654915b5fe6990fd17f54a150" + integrity sha512-G6/9xUqmt/r+UvufSyrPpt84NYwhKZ9jLsgMbQzlx804XErNupor8WQdBnBRrXmBfTPpuwf1sV+ss2ovjgdXIg== + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.1" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.21" + mute-stream "0.0.8" + ora "^5.4.1" + run-async "^2.4.0" + rxjs "^7.2.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + inquirer@~6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.3.1.tgz#7a413b5e7950811013a3db491c61d1f3b776e8e7" @@ -8792,7 +8817,7 @@ optionator@^0.8.1: type-check "~0.3.2" word-wrap "~1.2.3" -ora@5.4.1, ora@^5.1.0, ora@^5.3.0: +ora@5.4.1, ora@^5.1.0, ora@^5.3.0, ora@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== @@ -10569,7 +10594,7 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@7.3.5, semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: +semver@7.3.5, semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== diff --git a/src/analytics/analytics.module.ts b/src/analytics/analytics.module.ts index 3809bd58a..fe4a0653e 100644 --- a/src/analytics/analytics.module.ts +++ b/src/analytics/analytics.module.ts @@ -1,9 +1,11 @@ -import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders, APP_INITIALIZER } from '@angular/core'; +import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders, APP_INITIALIZER, Injector } from '@angular/core'; import { Analytics as FirebaseAnalytics, isSupported } from 'firebase/analytics'; -import { ɵgetDefaultInstanceOf, ɵmemoizeInstance, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; +import { ɵgetDefaultInstanceOf, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; import { Analytics, ANALYTICS_PROVIDER_NAME, AnalyticsInstances } from './analytics'; import { FirebaseApps, FirebaseApp } from '@angular/fire/app'; import { registerVersion } from 'firebase/app'; +import { ScreenTrackingService } from './screen-tracking.service'; +import { UserTrackingService } from './user-tracking.service'; const PROVIDED_ANALYTICS_INSTANCES = new InjectionToken('angularfire2.analytics-instances'); const IS_SUPPORTED = new InjectionToken('angularfire2.analytics.isSupported'); @@ -11,15 +13,15 @@ const IS_SUPPORTED = new InjectionToken('angularfire2.analytics.isSuppo const isSupportedSymbol = Symbol('angularfire2.analytics.isSupported'); export function defaultAnalyticsInstanceFactory(isSupported: boolean, provided: FirebaseAnalytics[]|undefined, defaultApp: FirebaseApp) { - const defaultAnalytics = isSupported ? - ɵgetDefaultInstanceOf(ANALYTICS_PROVIDER_NAME, provided, defaultApp) : - undefined; - return new Analytics(defaultAnalytics); + if (!isSupported) { return null; } + const defaultAnalytics = ɵgetDefaultInstanceOf(ANALYTICS_PROVIDER_NAME, provided, defaultApp); + return defaultAnalytics && new Analytics(defaultAnalytics); } -export function analyticsInstanceFactory(fn: () => FirebaseAnalytics) { - return (zone: NgZone, isSupported: boolean) => { - const analytics = isSupported ? ɵmemoizeInstance(fn, zone) : undefined; +export function analyticsInstanceFactory(fn: (injector: Injector) => FirebaseAnalytics) { + return (zone: NgZone, isSupported: boolean, injector: Injector) => { + if (!isSupported) { return null; } + const analytics = zone.runOutsideAngular(() => fn(injector)); return new Analytics(analytics); }; } @@ -53,12 +55,15 @@ const DEFAULT_ANALYTICS_INSTANCE_PROVIDER = { ] }) export class AnalyticsModule { - constructor() { + constructor( + @Optional() _screenTracking: ScreenTrackingService, + @Optional() _userTracking: UserTrackingService, + ) { registerVersion('angularfire', VERSION.full, 'analytics'); } } -export function provideAnalytics(fn: () => FirebaseAnalytics): ModuleWithProviders { +export function provideAnalytics(fn: (injector: Injector) => FirebaseAnalytics): ModuleWithProviders { return { ngModule: AnalyticsModule, providers: [{ @@ -71,6 +76,7 @@ export function provideAnalytics(fn: () => FirebaseAnalytics): ModuleWithProvide deps: [ NgZone, IS_SUPPORTED, + Injector, ɵAngularFireSchedulers, FirebaseApps, ] diff --git a/src/analytics/public_api.ts b/src/analytics/public_api.ts index e0550fcd9..ed2050781 100644 --- a/src/analytics/public_api.ts +++ b/src/analytics/public_api.ts @@ -1,3 +1,5 @@ export { Analytics, AnalyticsInstances, analyticInstance$ } from './analytics'; export { provideAnalytics, AnalyticsModule } from './analytics.module'; export * from './firebase'; +export * from './screen-tracking.service'; +export * from './user-tracking.service'; diff --git a/src/analytics/screen-tracking.service.ts b/src/analytics/screen-tracking.service.ts new file mode 100644 index 000000000..cc095447f --- /dev/null +++ b/src/analytics/screen-tracking.service.ts @@ -0,0 +1,176 @@ +import { ComponentFactoryResolver, Injectable, NgZone, OnDestroy, Optional } from '@angular/core'; +import { of, Subscription, Observable } from 'rxjs'; +import { distinctUntilChanged, filter, groupBy, map, mergeMap, pairwise, startWith, switchMap } from 'rxjs/operators'; +import { ActivationEnd, Router, ɵEmptyOutletComponent } from '@angular/router'; +import { Title } from '@angular/platform-browser'; +import { VERSION } from '@angular/fire'; +import { registerVersion } from 'firebase/app'; + +import { Analytics } from './analytics'; +import { logEvent } from './firebase'; +import { UserTrackingService } from './user-tracking.service'; + +const FIREBASE_EVENT_ORIGIN_KEY = 'firebase_event_origin'; +const FIREBASE_PREVIOUS_SCREEN_CLASS_KEY = 'firebase_previous_class'; +const FIREBASE_PREVIOUS_SCREEN_INSTANCE_ID_KEY = 'firebase_previous_id'; +const FIREBASE_PREVIOUS_SCREEN_NAME_KEY = 'firebase_previous_screen'; +const FIREBASE_SCREEN_CLASS_KEY = 'firebase_screen_class'; +const FIREBASE_SCREEN_INSTANCE_ID_KEY = 'firebase_screen_id'; +const FIREBASE_SCREEN_NAME_KEY = 'firebase_screen'; +const OUTLET_KEY = 'outlet'; +const PAGE_PATH_KEY = 'page_path'; +const PAGE_TITLE_KEY = 'page_title'; +const SCREEN_CLASS_KEY = 'screen_class'; +const SCREEN_NAME_KEY = 'screen_name'; +const SCREEN_VIEW_EVENT = 'screen_view'; +const EVENT_ORIGIN_AUTO = 'auto'; +const SCREEN_INSTANCE_DELIMITER = '#'; + +// this is an INT64 in iOS/Android but use INT32 cause javascript +let nextScreenInstanceID = Math.floor(Math.random() * (2 ** 32 - 1)) - 2 ** 31; + +const knownScreenInstanceIDs: { [key: string]: number } = {}; + +const getScreenInstanceID = (params: { [key: string]: any }) => { + // unique the screen class against the outlet name + const screenInstanceKey = [ + params[SCREEN_CLASS_KEY], + params[OUTLET_KEY] + ].join(SCREEN_INSTANCE_DELIMITER); + if (knownScreenInstanceIDs.hasOwnProperty(screenInstanceKey)) { + return knownScreenInstanceIDs[screenInstanceKey]; + } else { + const ret = nextScreenInstanceID++; + knownScreenInstanceIDs[screenInstanceKey] = ret; + return ret; + } +}; + +export const ɵscreenViewEvent = ( + router: Router, + title: Title|null, + componentFactoryResolver: ComponentFactoryResolver, +): Observable<{ + [SCREEN_NAME_KEY]: string, + [PAGE_PATH_KEY]: string, + [FIREBASE_EVENT_ORIGIN_KEY]: 'auto', + [FIREBASE_SCREEN_NAME_KEY]: string, + [OUTLET_KEY]: string, + [PAGE_TITLE_KEY]?: string, + [SCREEN_CLASS_KEY]: string, + [FIREBASE_SCREEN_CLASS_KEY]: string, + [FIREBASE_SCREEN_INSTANCE_ID_KEY]: number, + [FIREBASE_PREVIOUS_SCREEN_CLASS_KEY]: string, + [FIREBASE_PREVIOUS_SCREEN_NAME_KEY]: string, + [FIREBASE_PREVIOUS_SCREEN_INSTANCE_ID_KEY]: number, +}> => { + const activationEndEvents = router.events.pipe(filter(e => e instanceof ActivationEnd)); + return activationEndEvents.pipe( + switchMap|null>>(activationEnd => { + // router parseUrl is having trouble with outlets when they're empty + // e.g, /asdf/1(bob://sally:asdf), so put another slash in when empty + const urlTree = router.parseUrl(router.url.replace(/(?:\().+(?:\))/g, a => a.replace('://', ':///'))); + const pagePath = urlTree.root.children[activationEnd.snapshot.outlet]?.toString() || ''; + const actualSnapshot = router.routerState.root.children.map(it => it).find(it => it.outlet === activationEnd.snapshot.outlet); + + if (!actualSnapshot) { + return of(null); + } + + let actualDeep = actualSnapshot; + while (actualDeep.firstChild) { + actualDeep = actualDeep.firstChild; + } + const screenName = actualDeep.pathFromRoot.map(s => s.routeConfig?.path).filter(it => it).join('/') || '/'; + + const params = { + [SCREEN_NAME_KEY]: screenName, + [PAGE_PATH_KEY]: `/${pagePath}`, + [FIREBASE_EVENT_ORIGIN_KEY]: EVENT_ORIGIN_AUTO, + [FIREBASE_SCREEN_NAME_KEY]: screenName, + [OUTLET_KEY]: activationEnd.snapshot.outlet + }; + if (title) { + params[PAGE_TITLE_KEY] = title.getTitle(); + } + + let component = actualSnapshot.component; + if (component) { + if (component === ɵEmptyOutletComponent) { + let deepSnapshot = activationEnd.snapshot; + // TODO when might there be mutple children, different outlets? explore + while (deepSnapshot.firstChild) { + deepSnapshot = deepSnapshot.firstChild; + } + component = deepSnapshot.component; + } + } else { + component = activationEnd.snapshot.component; + } + + if (typeof component === 'string') { + return of({ ...params, [SCREEN_CLASS_KEY]: component }); + } else if (component) { + const componentFactory = componentFactoryResolver.resolveComponentFactory(component); + return of({ ...params, [SCREEN_CLASS_KEY]: componentFactory.selector }); + } + // lazy loads cause extra activations, ignore + return of(null); + }), + filter(it => !!it), + map(params => ({ + [FIREBASE_SCREEN_CLASS_KEY]: params[SCREEN_CLASS_KEY], + [FIREBASE_SCREEN_INSTANCE_ID_KEY]: getScreenInstanceID(params), + ...params + })), + groupBy(it => it[OUTLET_KEY]), + mergeMap(it => it.pipe( + distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)), + startWith(undefined), + pairwise(), + map(([prior, current]) => + prior ? { + [FIREBASE_PREVIOUS_SCREEN_CLASS_KEY]: prior[SCREEN_CLASS_KEY], + [FIREBASE_PREVIOUS_SCREEN_NAME_KEY]: prior[SCREEN_NAME_KEY], + [FIREBASE_PREVIOUS_SCREEN_INSTANCE_ID_KEY]: prior[FIREBASE_SCREEN_INSTANCE_ID_KEY], + ...current + } : current + ), + )) + ); +}; + +@Injectable() +export class ScreenTrackingService implements OnDestroy { + + private disposable: Subscription | undefined; + + constructor( + analytics: Analytics, + @Optional() router: Router, + @Optional() title: Title, + componentFactoryResolver: ComponentFactoryResolver, + zone: NgZone, + @Optional() userTrackingService: UserTrackingService, + ) { + registerVersion('angularfire', VERSION.full, 'screen-tracking'); + if (!analytics || !router) { return this; } + zone.runOutsideAngular(() => { + this.disposable = ɵscreenViewEvent(router, title, componentFactoryResolver).pipe( + switchMap(async params => { + if (userTrackingService) { + await userTrackingService.initialized; + } + return logEvent(analytics, SCREEN_VIEW_EVENT, params); + }) + ).subscribe(); + }); + } + + ngOnDestroy() { + if (this.disposable) { + this.disposable.unsubscribe(); + } + } + +} diff --git a/src/analytics/user-tracking.service.ts b/src/analytics/user-tracking.service.ts new file mode 100644 index 000000000..5d6cb04d8 --- /dev/null +++ b/src/analytics/user-tracking.service.ts @@ -0,0 +1,39 @@ +import { Injectable, NgZone, OnDestroy } from '@angular/core'; +import { Analytics } from './analytics'; +import { Subscription } from 'rxjs'; +import { VERSION } from '@angular/fire'; +import { Auth, authState } from '@angular/fire/auth'; +import { registerVersion } from 'firebase/app'; +import { setUserId } from './firebase'; + +@Injectable() +export class UserTrackingService implements OnDestroy { + + public readonly initialized: Promise; + private readonly disposables: Array = []; + + constructor( + analytics: Analytics, + auth: Auth, + zone: NgZone, + ) { + registerVersion('angularfire', VERSION.full, 'user-tracking'); + if (analytics) { + let resolveInitialized: () => void; + this.initialized = zone.runOutsideAngular(() => new Promise(resolve => { resolveInitialized = resolve; })); + this.disposables = [ + // TODO add credential tracking back in + authState(auth).subscribe(user => { + resolveInitialized(); + setUserId(analytics, user?.uid); + }), + ]; + } else { + this.initialized = Promise.reject(); + } + } + + ngOnDestroy() { + this.disposables.forEach(it => it.unsubscribe()); + } +} diff --git a/src/app-check/app-check.module.ts b/src/app-check/app-check.module.ts index 24f8f15a8..a0a131ba0 100644 --- a/src/app-check/app-check.module.ts +++ b/src/app-check/app-check.module.ts @@ -1,6 +1,6 @@ -import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders, PLATFORM_ID, isDevMode } from '@angular/core'; +import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders, PLATFORM_ID, isDevMode, Injector } from '@angular/core'; import { AppCheck as FirebaseAppCheck } from 'firebase/app-check'; -import { ɵgetDefaultInstanceOf, ɵmemoizeInstance, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; +import { ɵgetDefaultInstanceOf, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; import { AppCheck, AppCheckInstances, APP_CHECK_PROVIDER_NAME } from './app-check'; import { FirebaseApps, FirebaseApp } from '@angular/fire/app'; import { registerVersion } from 'firebase/app'; @@ -10,11 +10,11 @@ export const APP_CHECK_NAMESPACE_SYMBOL = Symbol('angularfire2.app-check.namespa export function defaultAppCheckInstanceFactory(provided: FirebaseAppCheck[]|undefined, defaultApp: FirebaseApp) { const defaultAppCheck = ɵgetDefaultInstanceOf(APP_CHECK_PROVIDER_NAME, provided, defaultApp); - return new AppCheck(defaultAppCheck); + return defaultAppCheck && new AppCheck(defaultAppCheck); } -export function appCheckInstanceFactory(fn: () => FirebaseAppCheck) { - return (zone: NgZone) => { +export function appCheckInstanceFactory(fn: (injector: Injector) => FirebaseAppCheck) { + return (zone: NgZone, injector: Injector) => { // This isn't supported by the JS SDK yet, I've put in the feature request // for the time being I've written a hack in core.ts /* if (typeof process !== 'undefined' && process.env?.FIREBASE_APPCHECK_DEBUG_TOKEN) { @@ -22,7 +22,8 @@ export function appCheckInstanceFactory(fn: () => FirebaseAppCheck) { } else if (isDevMode()) { globalThis.FIREBASE_APPCHECK_DEBUG_TOKEN ??= true; } */ - return ɵmemoizeInstance(fn, zone); + const appCheck = zone.runOutsideAngular(() => fn(injector)); + return new AppCheck(appCheck); }; } @@ -55,7 +56,7 @@ export class AppCheckModule { } } -export function provideAppCheck(fn: () => FirebaseAppCheck): ModuleWithProviders { +export function provideAppCheck(fn: (injector: Injector) => FirebaseAppCheck): ModuleWithProviders { return { ngModule: AppCheckModule, providers: [{ @@ -64,7 +65,7 @@ export function provideAppCheck(fn: () => FirebaseAppCheck): ModuleWithProviders multi: true, deps: [ NgZone, - PLATFORM_ID, + Injector, ɵAngularFireSchedulers, FirebaseApps, ] diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 33c3e72fb..31e087acf 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,6 +1,7 @@ import { Inject, InjectionToken, + Injector, ModuleWithProviders, NgModule, NgZone, @@ -11,7 +12,7 @@ import { import { FirebaseApp as IFirebaseApp, getApp, registerVersion } from 'firebase/app'; import { FirebaseApp, FirebaseApps } from './app'; -import { VERSION, ɵmemoizeInstance, ɵAngularFireSchedulers } from '@angular/fire'; +import { VERSION, ɵAngularFireSchedulers } from '@angular/fire'; export function defaultFirebaseAppFactory(provided: FirebaseApp[]|undefined) { // Use the provided app, if there is only one, otherwise fetch the default app @@ -42,9 +43,9 @@ const FIREBASE_APPS_PROVIDER = { ], }; -export function firebaseAppFactory(fn: () => IFirebaseApp) { - return (zone: NgZone) => { - const app = ɵmemoizeInstance(fn, zone); +export function firebaseAppFactory(fn: (injector: Injector) => IFirebaseApp) { + return (zone: NgZone, injector: Injector) => { + const app = zone.runOutsideAngular(() => fn(injector)); return new FirebaseApp(app); }; } @@ -74,7 +75,11 @@ export function provideFirebaseApp(fn: () => IFirebaseApp): ModuleWithProviders< provide: PROVIDED_FIREBASE_APPS, useFactory: firebaseAppFactory(fn), multi: true, - deps: [ NgZone, ɵAngularFireSchedulers ], + deps: [ + NgZone, + Injector, + ɵAngularFireSchedulers + ], }], }; } diff --git a/src/auth/auth.module.ts b/src/auth/auth.module.ts index 31578eeb0..d6e61b35a 100644 --- a/src/auth/auth.module.ts +++ b/src/auth/auth.module.ts @@ -1,6 +1,6 @@ -import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders, PLATFORM_ID } from '@angular/core'; +import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders, Injector } from '@angular/core'; import { Auth as FirebaseAuth } from 'firebase/auth'; -import { ɵgetDefaultInstanceOf, ɵmemoizeInstance, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; +import { ɵgetDefaultInstanceOf, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; import { Auth, AuthInstances, AUTH_PROVIDER_NAME } from './auth'; import { FirebaseApps, FirebaseApp } from '@angular/fire/app'; import { registerVersion } from 'firebase/app'; @@ -10,12 +10,13 @@ export const PROVIDED_AUTH_INSTANCES = new InjectionToken('angularfire2. export function defaultAuthInstanceFactory(provided: FirebaseAuth[]|undefined, defaultApp: FirebaseApp) { const defaultAuth = ɵgetDefaultInstanceOf(AUTH_PROVIDER_NAME, provided, defaultApp); - return new Auth(defaultAuth); + return defaultAuth && new Auth(defaultAuth); } -export function authInstanceFactory(fn: () => FirebaseAuth) { - return (zone: NgZone) => { - return ɵmemoizeInstance(fn, zone); +export function authInstanceFactory(fn: (injector: Injector) => FirebaseAuth) { + return (zone: NgZone, injector: Injector) => { + const auth = zone.runOutsideAngular(() => fn(injector)); + return new Auth(auth); }; } @@ -32,7 +33,6 @@ const DEFAULT_AUTH_INSTANCE_PROVIDER = { deps: [ [new Optional(), PROVIDED_AUTH_INSTANCES ], FirebaseApp, - PLATFORM_ID, ] }; @@ -57,7 +57,7 @@ export function provideAuth(fn: () => FirebaseAuth): ModuleWithProviders { - // unique the screen class against the outlet name - const screenInstanceKey = [ - params[SCREEN_CLASS_KEY], - params[OUTLET_KEY] - ].join(SCREEN_INSTANCE_DELIMITER); - if (knownScreenInstanceIDs.hasOwnProperty(screenInstanceKey)) { - return knownScreenInstanceIDs[screenInstanceKey]; - } else { - const ret = nextScreenInstanceID++; - knownScreenInstanceIDs[screenInstanceKey] = ret; - return ret; - } -}; @Injectable() export class ScreenTrackingService implements OnDestroy { @@ -63,96 +21,19 @@ export class ScreenTrackingService implements OnDestroy { @Optional() router: Router, @Optional() title: Title, componentFactoryResolver: ComponentFactoryResolver, - // tslint:disable-next-line:ban-types - @Inject(PLATFORM_ID) platformId: Object, zone: NgZone, @Optional() userTrackingService: UserTrackingService, ) { firebase.registerVersion('angularfire', VERSION.full, 'compat-screen-tracking'); - if (!router || !isPlatformBrowser(platformId)) { - return this; - } + if (!router || !analytics) { return this; } zone.runOutsideAngular(() => { - const activationEndEvents = router.events.pipe(filter(e => e instanceof ActivationEnd)); - this.disposable = activationEndEvents.pipe( - switchMap(activationEnd => { - // router parseUrl is having trouble with outlets when they're empty - // e.g, /asdf/1(bob://sally:asdf), so put another slash in when empty - const urlTree = router.parseUrl(router.url.replace(/(?:\().+(?:\))/g, a => a.replace('://', ':///'))); - const pagePath = urlTree.root.children[activationEnd.snapshot.outlet]?.toString() || ''; - const actualSnapshot = router.routerState.root.children.map(it => it).find(it => it.outlet === activationEnd.snapshot.outlet); - - if (!actualSnapshot) { - return of(null); - } - - let actualDeep = actualSnapshot; - while (actualDeep.firstChild) { - actualDeep = actualDeep.firstChild; - } - const screenName = actualDeep.pathFromRoot.map(s => s.routeConfig?.path).filter(it => it).join('/') || '/'; - - const params = { - [SCREEN_NAME_KEY]: screenName, - [PAGE_PATH_KEY]: `/${pagePath}`, - [FIREBASE_EVENT_ORIGIN_KEY]: EVENT_ORIGIN_AUTO, - [FIREBASE_SCREEN_NAME_KEY]: screenName, - [OUTLET_KEY]: activationEnd.snapshot.outlet - }; - if (title) { - params[PAGE_TITLE_KEY] = title.getTitle(); - } - - let component = actualSnapshot.component; - if (component) { - if (component === ɵEmptyOutletComponent) { - let deepSnapshot = activationEnd.snapshot; - // TODO when might there be mutple children, different outlets? explore - while (deepSnapshot.firstChild) { - deepSnapshot = deepSnapshot.firstChild; - } - component = deepSnapshot.component; - } - } else { - component = activationEnd.snapshot.component; - } - - if (typeof component === 'string') { - return of({ ...params, [SCREEN_CLASS_KEY]: component }); - } else if (component) { - const componentFactory = componentFactoryResolver.resolveComponentFactory(component); - return of({ ...params, [SCREEN_CLASS_KEY]: componentFactory.selector }); - } else { - // lazy loads cause extra activations, ignore - return of(null); - } - }), - filter(it => it), - map(params => ({ - [FIREBASE_SCREEN_CLASS_KEY]: params[SCREEN_CLASS_KEY], - [FIREBASE_SCREEN_INSTANCE_ID_KEY]: getScreenInstanceID(params), - ...params - })), - groupBy(it => it[OUTLET_KEY]), - mergeMap(it => it.pipe( - distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)), - startWith(undefined), - pairwise(), - map(([prior, current]) => - prior ? { - [FIREBASE_PREVIOUS_SCREEN_CLASS_KEY]: prior[SCREEN_CLASS_KEY], - [FIREBASE_PREVIOUS_SCREEN_NAME_KEY]: prior[SCREEN_NAME_KEY], - [FIREBASE_PREVIOUS_SCREEN_INSTANCE_ID_KEY]: prior[FIREBASE_SCREEN_INSTANCE_ID_KEY], - ...current - } : current - ), + this.disposable = ɵscreenViewEvent(router, title, componentFactoryResolver).pipe( switchMap(async params => { if (userTrackingService) { await userTrackingService.initialized; } return await analytics.logEvent(SCREEN_VIEW_EVENT, params); }) - )) ).subscribe(); }); } diff --git a/src/compat/auth/auth.ts b/src/compat/auth/auth.ts index 3f5751620..d10c69bd1 100644 --- a/src/compat/auth/auth.ts +++ b/src/compat/auth/auth.ts @@ -3,12 +3,11 @@ import { Observable, of, from, merge, Subject } from 'rxjs'; import { switchMap, map, observeOn, shareReplay, first, filter, switchMapTo, subscribeOn } from 'rxjs/operators'; import { ɵAngularFireSchedulers, keepUnstableUntilFirst } from '@angular/fire'; import { ɵlazySDKProxy, ɵPromiseProxy, ɵapplyMixins } from '@angular/fire/compat'; -import { ɵfirebaseAppFactory, FIREBASE_OPTIONS, FIREBASE_APP_NAME, FirebaseApp } from '@angular/fire/compat'; +import { ɵfirebaseAppFactory, FIREBASE_OPTIONS, FIREBASE_APP_NAME, FirebaseApp, ɵcacheInstance } from '@angular/fire/compat'; import { FirebaseOptions } from 'firebase/app'; import firebase from 'firebase/compat/app'; import { isPlatformServer } from '@angular/common'; import { proxyPolyfillCompat } from './base'; -import { ɵcacheInstance } from '@angular/fire'; import { AppCheckInstances } from '@angular/fire/app-check'; export interface AngularFireAuth extends ɵPromiseProxy {} diff --git a/src/compat/cache.ts b/src/compat/cache.ts new file mode 100644 index 000000000..5ab2c2d8f --- /dev/null +++ b/src/compat/cache.ts @@ -0,0 +1,34 @@ +import { isDevMode } from '@angular/core'; + +export function ɵcacheInstance(cacheKey: any, moduleName: string, appName: string, fn: () => T, deps: any): T { + const [, instance, cachedDeps] = globalThis.ɵAngularfireInstanceCache.find((it: any) => it[0] === cacheKey) || []; + if (instance) { + if (!matchDep(deps, cachedDeps)) { + log('error', `${moduleName} was already initialized on the ${appName} Firebase App with different settings.${IS_HMR ? ' You may need to reload as Firebase is not HMR aware.' : ''}`); + log('warn', {is: deps, was: cachedDeps}); + } + return instance; + } else { + const newInstance = fn(); + globalThis.ɵAngularfireInstanceCache.push([cacheKey, newInstance, deps]); + return newInstance; + } +} + +function matchDep(a: any, b: any) { + try { + return a.toString() === b.toString(); + } catch (_) { + return a === b; + } +} + +const IS_HMR = !!(module as any).hot; + +const log = (level: 'log'|'error'|'info'|'warn', ...args: any) => { + if (isDevMode() && typeof console !== 'undefined') { + console[level](...args); + } +}; + +globalThis.ɵAngularfireInstanceCache ||= []; diff --git a/src/compat/database/database.ts b/src/compat/database/database.ts index 7fd725147..23c8fd1e3 100644 --- a/src/compat/database/database.ts +++ b/src/compat/database/database.ts @@ -5,7 +5,7 @@ import { createListReference } from './list/create-reference'; import { createObjectReference } from './object/create-reference'; import { ɵAngularFireSchedulers } from '@angular/fire'; import { FirebaseOptions } from 'firebase/app'; -import { ɵfirebaseAppFactory, FIREBASE_APP_NAME, FIREBASE_OPTIONS } from '@angular/fire/compat'; +import { ɵfirebaseAppFactory, FIREBASE_APP_NAME, FIREBASE_OPTIONS, ɵcacheInstance } from '@angular/fire/compat'; import 'firebase/compat/auth'; import 'firebase/compat/database'; import { @@ -19,7 +19,6 @@ import { ɵauthFactory, } from '@angular/fire/compat/auth'; import firebase from 'firebase/compat/app'; -import { ɵcacheInstance } from '@angular/fire'; import { AppCheckInstances } from '@angular/fire/app-check'; export const URL = new InjectionToken('angularfire2.realtimeDatabaseURL'); diff --git a/src/compat/firestore/firestore.ts b/src/compat/firestore/firestore.ts index d6bec8ac7..8a31a8063 100644 --- a/src/compat/firestore/firestore.ts +++ b/src/compat/firestore/firestore.ts @@ -14,7 +14,7 @@ import { AngularFirestoreDocument } from './document/document'; import { AngularFirestoreCollection } from './collection/collection'; import { AngularFirestoreCollectionGroup } from './collection-group/collection-group'; import { ɵAngularFireSchedulers } from '@angular/fire'; -import { FirebaseApp, ɵfirebaseAppFactory, FIREBASE_APP_NAME, FIREBASE_OPTIONS } from '@angular/fire/compat'; +import { FirebaseApp, ɵfirebaseAppFactory, FIREBASE_APP_NAME, FIREBASE_OPTIONS, ɵcacheInstance } from '@angular/fire/compat'; import { FirebaseOptions } from 'firebase/app'; import { isPlatformServer } from '@angular/common'; import firebase from 'firebase/compat/app'; @@ -30,7 +30,6 @@ import { PERSISTENCE, ɵauthFactory, } from '@angular/fire/compat/auth'; -import { ɵcacheInstance } from '@angular/fire'; import { AppCheckInstances } from '@angular/fire/app-check'; /** diff --git a/src/compat/functions/functions.ts b/src/compat/functions/functions.ts index dedf6d2d4..1971ae4e3 100644 --- a/src/compat/functions/functions.ts +++ b/src/compat/functions/functions.ts @@ -4,11 +4,10 @@ import { map, observeOn, shareReplay, switchMap } from 'rxjs/operators'; import { ɵAngularFireSchedulers } from '@angular/fire'; import { ɵlazySDKProxy, ɵPromiseProxy, ɵapplyMixins } from '@angular/fire/compat'; import { FirebaseOptions } from 'firebase/app'; -import { ɵfirebaseAppFactory, FIREBASE_APP_NAME, FIREBASE_OPTIONS } from '@angular/fire/compat'; +import { ɵfirebaseAppFactory, FIREBASE_APP_NAME, FIREBASE_OPTIONS, ɵcacheInstance } from '@angular/fire/compat'; import firebase from 'firebase/compat/app'; import { proxyPolyfillCompat } from './base'; import { HttpsCallableOptions } from '@firebase/functions-types'; -import { ɵcacheInstance } from '@angular/fire'; import { AppCheckInstances } from '@angular/fire/app-check'; export const ORIGIN = new InjectionToken('angularfire2.functions.origin'); diff --git a/src/compat/messaging/messaging.ts b/src/compat/messaging/messaging.ts index a3858e49d..b46d4950d 100644 --- a/src/compat/messaging/messaging.ts +++ b/src/compat/messaging/messaging.ts @@ -2,9 +2,9 @@ import { Inject, Injectable, InjectionToken, NgZone, Optional, PLATFORM_ID } fro import firebase from 'firebase/compat/app'; import { concat, EMPTY, Observable, of } from 'rxjs'; import { catchError, defaultIfEmpty, map, mergeMap, observeOn, switchMap, switchMapTo, shareReplay, subscribeOn } from 'rxjs/operators'; -import { ɵAngularFireSchedulers, ɵcacheInstance } from '@angular/fire'; +import { ɵAngularFireSchedulers } from '@angular/fire'; import { ɵlazySDKProxy, ɵPromiseProxy, ɵapplyMixins } from '@angular/fire/compat'; -import { ɵfirebaseAppFactory, FIREBASE_APP_NAME, FIREBASE_OPTIONS } from '@angular/fire/compat'; +import { ɵfirebaseAppFactory, FIREBASE_APP_NAME, FIREBASE_OPTIONS, ɵcacheInstance } from '@angular/fire/compat'; import { FirebaseOptions } from 'firebase/app'; import { proxyPolyfillCompat } from './base'; import { isSupported } from 'firebase/messaging'; diff --git a/src/compat/performance/performance.ts b/src/compat/performance/performance.ts index 5bc217509..06d6f6b29 100644 --- a/src/compat/performance/performance.ts +++ b/src/compat/performance/performance.ts @@ -2,8 +2,7 @@ import { Inject, Injectable, InjectionToken, NgZone, Optional, PLATFORM_ID } fro import { EMPTY, Observable, of, Subscription } from 'rxjs'; import { map, shareReplay, switchMap, tap } from 'rxjs/operators'; import firebase from 'firebase/compat/app'; -import { ɵapplyMixins, ɵlazySDKProxy, ɵPromiseProxy } from '@angular/fire/compat'; -import { ɵcacheInstance } from '@angular/fire'; +import { ɵapplyMixins, ɵlazySDKProxy, ɵPromiseProxy, ɵcacheInstance } from '@angular/fire/compat'; import { FirebaseApp } from '@angular/fire/compat'; import { isPlatformBrowser } from '@angular/common'; import { proxyPolyfillCompat } from './base'; diff --git a/src/compat/public_api.ts b/src/compat/public_api.ts index 97ef12b95..3d5ea5ea3 100644 --- a/src/compat/public_api.ts +++ b/src/compat/public_api.ts @@ -1,3 +1,4 @@ export * from './proxy'; export * from './firebase.app'; export * from './firebase.app.module'; +export * from './cache'; diff --git a/src/compat/remote-config/remote-config.ts b/src/compat/remote-config/remote-config.ts index 1be4822b5..df5c99e88 100644 --- a/src/compat/remote-config/remote-config.ts +++ b/src/compat/remote-config/remote-config.ts @@ -17,12 +17,11 @@ import { import { ɵAngularFireSchedulers, keepUnstableUntilFirst } from '@angular/fire'; import { ɵlazySDKProxy, ɵPromiseProxy, ɵapplyMixins } from '@angular/fire/compat'; import { FirebaseOptions } from 'firebase/app'; -import { ɵfirebaseAppFactory, FIREBASE_APP_NAME, FIREBASE_OPTIONS } from '@angular/fire/compat'; +import { ɵfirebaseAppFactory, FIREBASE_APP_NAME, FIREBASE_OPTIONS, ɵcacheInstance } from '@angular/fire/compat'; import { isPlatformBrowser } from '@angular/common'; import firebase from 'firebase/compat/app'; import { Settings } from './interfaces'; import { proxyPolyfillCompat } from './base'; -import { ɵcacheInstance } from '@angular/fire'; export interface ConfigTemplate { [key: string]: string | number | boolean; diff --git a/src/compat/storage/storage.ts b/src/compat/storage/storage.ts index 21c732a45..6868d5fd9 100644 --- a/src/compat/storage/storage.ts +++ b/src/compat/storage/storage.ts @@ -1,8 +1,8 @@ import { Inject, Injectable, InjectionToken, NgZone, Optional, PLATFORM_ID } from '@angular/core'; import { createStorageRef } from './ref'; -import { ɵAngularFireSchedulers, ɵcacheInstance } from '@angular/fire'; +import { ɵAngularFireSchedulers } from '@angular/fire'; import { FirebaseOptions } from 'firebase/app'; -import { ɵfirebaseAppFactory, FIREBASE_APP_NAME, FIREBASE_OPTIONS } from '@angular/fire/compat'; +import { ɵfirebaseAppFactory, FIREBASE_APP_NAME, FIREBASE_OPTIONS, ɵcacheInstance } from '@angular/fire/compat'; import { UploadMetadata } from './interfaces'; import 'firebase/compat/storage'; import firebase from 'firebase/compat/app'; diff --git a/src/core.ts b/src/core.ts index 3ba9b4233..6b959c704 100644 --- a/src/core.ts +++ b/src/core.ts @@ -9,60 +9,21 @@ interface FirebaseAppWithContainer extends FirebaseApp { container: ComponentContainer; } -const IS_HMR = !!(module as any).hot; - -const log = (level: 'log'|'error'|'info'|'warn', ...args: any) => { - if (isDevMode() && typeof console !== 'undefined') { - console[level](...args); - } -}; - -export function ɵcacheInstance(cacheKey: any, moduleName: string, appName: string, fn: () => T, deps: any): T { - const [, instance, cachedDeps] = globalThis.ɵAngularfireInstanceCache.find((it: any) => it[0] === cacheKey) || []; - if (instance) { - if (!matchDep(deps, cachedDeps)) { - log('error', `${moduleName} was already initialized on the ${appName} Firebase App with different settings.${IS_HMR ? ' You may need to reload as Firebase is not HMR aware.' : ''}`); - log('warn', {is: deps, was: cachedDeps}); - } - return instance; - } else { - const newInstance = fn(); - globalThis.ɵAngularfireInstanceCache.push([cacheKey, newInstance, deps]); - return newInstance; - } -} - -globalThis.ɵAngularfireInstanceCache ||= []; +const LOCALHOSTS = ['localhost', '0.0.0.0', '127.0.0.1']; // HACK HACK HACK // AppCheck stuff, here so we can get a jump on it. It's too late in the evaluation // if we do this in the app-check module. globalThis.ngDevMode allows me to test if // Angular is in DevMode before Angular initializes. // Only do this in the browser, for Node we have the admin sdk -if ((typeof process === 'undefined' || !process.versions?.node) && globalThis.ngDevMode) { +if (( + typeof process === 'undefined' || !process.versions?.node +) && ( + globalThis.ngDevMode || typeof window !== 'undefined' && LOCALHOSTS.includes(window.location.hostname) +)) { globalThis.FIREBASE_APPCHECK_DEBUG_TOKEN ??= true; } -export function ɵmemoizeInstance(fn: () => T, zone: NgZone): T { - const [, instance] = globalThis.ɵAngularfireInstanceCache.find((it: any) => matchDep(it[0], fn)) || []; - if (instance) { - return instance as T; - } else { - // TODO catch and add HMR warning - const instance = zone.runOutsideAngular(() => fn()); - globalThis.ɵAngularfireInstanceCache.push([fn, instance]); - return instance; - } -} - -function matchDep(a: any, b: any) { - try { - return a.toString() === b.toString(); - } catch (_) { - return a === b; - } -} - export function ɵgetDefaultInstanceOf(identifier: string, provided: T[]|undefined, defaultApp: FirebaseApp): T|undefined { if (provided) { // Was provide* only called once? If so grab that @@ -74,7 +35,7 @@ export function ɵgetDefaultInstanceOf(identifier: string, provided: // Grab the default instance from the defaultApp const defaultAppWithContainer: FirebaseAppWithContainer = defaultApp as any; const provider = defaultAppWithContainer.container.getProvider(identifier as never); - return provider.getImmediate(); + return provider.getImmediate({ optional: true }); } export const ɵgetAllInstancesOf = (identifier: string, app?: FirebaseApp): Array => { diff --git a/src/database/database.module.ts b/src/database/database.module.ts index 4bb178f74..95251bf0c 100644 --- a/src/database/database.module.ts +++ b/src/database/database.module.ts @@ -1,7 +1,7 @@ -import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders } from '@angular/core'; +import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders, Injector } from '@angular/core'; import { Database as FirebaseDatabase } from 'firebase/database'; import { AuthInstances } from '@angular/fire/auth'; -import { ɵgetDefaultInstanceOf, ɵmemoizeInstance, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; +import { ɵgetDefaultInstanceOf, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; import { Database, DatabaseInstances, DATABASE_PROVIDER_NAME } from './database'; import { FirebaseApps, FirebaseApp } from '@angular/fire/app'; import { registerVersion } from 'firebase/app'; @@ -11,12 +11,12 @@ export const PROVIDED_DATABASE_INSTANCES = new InjectionToken('angul export function defaultDatabaseInstanceFactory(provided: FirebaseDatabase[]|undefined, defaultApp: FirebaseApp) { const defaultDatabase = ɵgetDefaultInstanceOf(DATABASE_PROVIDER_NAME, provided, defaultApp); - return new Database(defaultDatabase); + return defaultDatabase && new Database(defaultDatabase); } -export function databaseInstanceFactory(fn: () => FirebaseDatabase) { - return (zone: NgZone) => { - const database = ɵmemoizeInstance(fn, zone); +export function databaseInstanceFactory(fn: (injector: Injector) => FirebaseDatabase) { + return (zone: NgZone, injector: Injector) => { + const database = zone.runOutsideAngular(() => fn(injector)); return new Database(database); }; } @@ -58,6 +58,7 @@ export function provideDatabase(fn: () => FirebaseDatabase): ModuleWithProviders multi: true, deps: [ NgZone, + Injector, ɵAngularFireSchedulers, FirebaseApps, // Database+Auth work better if Auth is loaded first diff --git a/src/firestore/firestore.module.ts b/src/firestore/firestore.module.ts index a55218ad0..6ba571f78 100644 --- a/src/firestore/firestore.module.ts +++ b/src/firestore/firestore.module.ts @@ -1,7 +1,7 @@ -import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders } from '@angular/core'; +import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders, Injector } from '@angular/core'; import { Firestore as FirebaseFirestore } from 'firebase/firestore'; import { AuthInstances } from '@angular/fire/auth'; -import { ɵmemoizeInstance, ɵgetDefaultInstanceOf, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; +import { ɵgetDefaultInstanceOf, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; import { Firestore, FirestoreInstances, FIRESTORE_PROVIDER_NAME } from './firestore'; import { FirebaseApps, FirebaseApp } from '@angular/fire/app'; import { registerVersion } from 'firebase/app'; @@ -11,14 +11,12 @@ export const PROVIDED_FIRESTORE_INSTANCES = new InjectionToken('ang export function defaultFirestoreInstanceFactory(provided: FirebaseFirestore[]|undefined, defaultApp: FirebaseApp) { const defaultFirestore = ɵgetDefaultInstanceOf(FIRESTORE_PROVIDER_NAME, provided, defaultApp); - // TODO how do I throw if it's undefined, unless @Optional(), is there an Angular NULL_INJECTOR token - // or something, can I use an @NgModule providers or something? - return new Firestore(defaultFirestore); + return defaultFirestore && new Firestore(defaultFirestore); } -export function firestoreInstanceFactory(fn: () => FirebaseFirestore) { - return (zone: NgZone) => { - const firestore = ɵmemoizeInstance(fn, zone); +export function firestoreInstanceFactory(fn: (injector: Injector) => FirebaseFirestore) { + return (zone: NgZone, injector: Injector) => { + const firestore = zone.runOutsideAngular(() => fn(injector)); return new Firestore(firestore); }; } @@ -60,6 +58,7 @@ export function provideFirestore(fn: () => FirebaseFirestore): ModuleWithProvide multi: true, deps: [ NgZone, + Injector, ɵAngularFireSchedulers, FirebaseApps, // Firestore+Auth work better if Auth is loaded first diff --git a/src/firestore/lite/lite.module.ts b/src/firestore/lite/lite.module.ts index 2aa66f416..13503a675 100644 --- a/src/firestore/lite/lite.module.ts +++ b/src/firestore/lite/lite.module.ts @@ -1,7 +1,7 @@ -import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders } from '@angular/core'; +import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders, Injector } from '@angular/core'; import { Firestore as FirebaseFirestore } from 'firebase/firestore/lite'; import { AuthInstances } from '@angular/fire/auth'; -import { ɵmemoizeInstance, ɵgetDefaultInstanceOf, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; +import { ɵgetDefaultInstanceOf, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; import { Firestore, FirestoreInstances, FIRESTORE_PROVIDER_NAME } from './lite'; import { FirebaseApps, FirebaseApp } from '@angular/fire/app'; import { registerVersion } from 'firebase/app'; @@ -10,12 +10,12 @@ export const PROVIDED_FIRESTORE_INSTANCES = new InjectionToken('ang export function defaultFirestoreInstanceFactory(provided: FirebaseFirestore[]|undefined, defaultApp: FirebaseApp) { const defaultFirestore = ɵgetDefaultInstanceOf(FIRESTORE_PROVIDER_NAME, provided, defaultApp); - return new Firestore(defaultFirestore); + return defaultFirestore && new Firestore(defaultFirestore); } -export function firestoreInstanceFactory(fn: () => FirebaseFirestore) { - return (zone: NgZone) => { - const firestore = ɵmemoizeInstance(fn, zone); +export function firestoreInstanceFactory(fn: (injector: Injector) => FirebaseFirestore) { + return (zone: NgZone, injector: Injector) => { + const firestore = zone.runOutsideAngular(() => fn(injector)); return new Firestore(firestore); }; } @@ -57,6 +57,7 @@ export function provideFirestore(fn: () => FirebaseFirestore): ModuleWithProvide multi: true, deps: [ NgZone, + Injector, ɵAngularFireSchedulers, FirebaseApps, // Firestore+Auth work better if Auth is loaded first diff --git a/src/functions/functions.module.ts b/src/functions/functions.module.ts index 8bccf163d..9cd0354c1 100644 --- a/src/functions/functions.module.ts +++ b/src/functions/functions.module.ts @@ -1,6 +1,6 @@ -import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders } from '@angular/core'; +import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders, Injector } from '@angular/core'; import { Functions as FirebaseFunctions } from 'firebase/functions'; -import { ɵgetDefaultInstanceOf, ɵmemoizeInstance, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; +import { ɵgetDefaultInstanceOf, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; import { Functions, FunctionsInstances, FUNCTIONS_PROVIDER_NAME } from './functions'; import { FirebaseApps, FirebaseApp } from '@angular/fire/app'; import { AuthInstances } from '@angular/fire/auth'; @@ -11,12 +11,12 @@ export const PROVIDED_FUNCTIONS_INSTANCES = new InjectionToken('ang export function defaultFunctionsInstanceFactory(provided: FirebaseFunctions[]|undefined, defaultApp: FirebaseApp) { const defaultAuth = ɵgetDefaultInstanceOf(FUNCTIONS_PROVIDER_NAME, provided, defaultApp); - return new Functions(defaultAuth); + return defaultAuth && new Functions(defaultAuth); } -export function functionsInstanceFactory(fn: () => FirebaseFunctions) { - return (zone: NgZone) => { - const functions = ɵmemoizeInstance(fn, zone); +export function functionsInstanceFactory(fn: (injector: Injector) => FirebaseFunctions) { + return (zone: NgZone, injector: Injector) => { + const functions = zone.runOutsideAngular(() => fn(injector)); return new Functions(functions); }; } @@ -58,6 +58,7 @@ export function provideFunctions(fn: () => FirebaseFunctions): ModuleWithProvide multi: true, deps: [ NgZone, + Injector, ɵAngularFireSchedulers, FirebaseApps, // Defensively load Auth first, if provided diff --git a/src/messaging/messaging.module.ts b/src/messaging/messaging.module.ts index 2e59dd36b..5ed8863dd 100644 --- a/src/messaging/messaging.module.ts +++ b/src/messaging/messaging.module.ts @@ -1,6 +1,6 @@ -import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders, APP_INITIALIZER } from '@angular/core'; +import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders, APP_INITIALIZER, Injector } from '@angular/core'; import { isSupported, Messaging as FirebaseMessaging } from 'firebase/messaging'; -import { ɵgetDefaultInstanceOf, ɵmemoizeInstance, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; +import { ɵgetDefaultInstanceOf, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; import { Messaging, MessagingInstances, MESSAGING_PROVIDER_NAME } from './messaging'; import { FirebaseApps, FirebaseApp } from '@angular/fire/app'; import { registerVersion } from 'firebase/app'; @@ -11,15 +11,15 @@ const IS_SUPPORTED = new InjectionToken('angularfire2.messaging.isSuppo const isSupportedSymbol = Symbol('angularfire2.messaging.isSupported'); export function defaultMessagingInstanceFactory(isSupported: boolean, provided: FirebaseMessaging[]|undefined, defaultApp: FirebaseApp) { - const defaultAuth = isSupported ? - ɵgetDefaultInstanceOf(MESSAGING_PROVIDER_NAME, provided, defaultApp) : - undefined; - return new Messaging(defaultAuth); + if (!isSupported) { return null; } + const defaultMessaging = ɵgetDefaultInstanceOf(MESSAGING_PROVIDER_NAME, provided, defaultApp); + return defaultMessaging && new Messaging(defaultMessaging); } -export function messagingInstanceFactory(fn: () => FirebaseMessaging) { - return (zone: NgZone, isSupported: boolean) => { - const messaging = isSupported ? ɵmemoizeInstance(fn, zone) : undefined; +export function messagingInstanceFactory(fn: (injector: Injector) => FirebaseMessaging) { + return (zone: NgZone, isSupported: boolean, injector: Injector) => { + if (!isSupported) { return null; } + const messaging = zone.runOutsideAngular(() => fn(injector)); return new Messaging(messaging); }; } @@ -71,6 +71,7 @@ export function provideMessaging(fn: () => FirebaseMessaging): ModuleWithProvide deps: [ NgZone, IS_SUPPORTED, + Injector, ɵAngularFireSchedulers, FirebaseApps, ], diff --git a/src/performance/performance.module.ts b/src/performance/performance.module.ts index d87a0d315..106806fbb 100644 --- a/src/performance/performance.module.ts +++ b/src/performance/performance.module.ts @@ -1,20 +1,29 @@ -import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders } from '@angular/core'; +import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders, PLATFORM_ID, Injector } from '@angular/core'; import { FirebasePerformance } from 'firebase/performance'; -import { ɵgetDefaultInstanceOf, ɵmemoizeInstance, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; +import { ɵgetDefaultInstanceOf, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; import { Performance, PerformanceInstances, PERFORMANCE_PROVIDER_NAME } from './performance'; import { FirebaseApps, FirebaseApp } from '@angular/fire/app'; import { registerVersion } from 'firebase/app'; +import { isPlatformBrowser } from '@angular/common'; export const PROVIDED_PERFORMANCE_INSTANCES = new InjectionToken('angularfire2.performance-instances'); -export function defaultPerformanceInstanceFactory(provided: FirebasePerformance[]|undefined, defaultApp: FirebaseApp) { +export function defaultPerformanceInstanceFactory( + provided: FirebasePerformance[]|undefined, + defaultApp: FirebaseApp, + // tslint:disable-next-line:ban-types + platform: Object +) { + if (!isPlatformBrowser(platform)) { return null; } const defaultPerformance = ɵgetDefaultInstanceOf(PERFORMANCE_PROVIDER_NAME, provided, defaultApp); - return new Performance(defaultPerformance); + return defaultPerformance && new Performance(defaultPerformance); } -export function performanceInstanceFactory(fn: () => FirebasePerformance) { - return (zone: NgZone) => { - const performance = ɵmemoizeInstance(fn, zone); +export function performanceInstanceFactory(fn: (injector: Injector) => FirebasePerformance) { + // tslint:disable-next-line:ban-types + return (zone: NgZone, platform: Object, injector: Injector) => { + if (!isPlatformBrowser(platform)) { return null; } + const performance = zone.runOutsideAngular(() => fn(injector)); return new Performance(performance); }; } @@ -32,6 +41,7 @@ const DEFAULT_PERFORMANCE_INSTANCE_PROVIDER = { deps: [ [new Optional(), PROVIDED_PERFORMANCE_INSTANCES ], FirebaseApp, + PLATFORM_ID, ] }; @@ -56,6 +66,8 @@ export function providePerformance(fn: () => FirebasePerformance): ModuleWithPro multi: true, deps: [ NgZone, + PLATFORM_ID, + Injector, ɵAngularFireSchedulers, FirebaseApps, ] diff --git a/src/remote-config/remote-config.module.ts b/src/remote-config/remote-config.module.ts index e28caf98a..d50b65433 100644 --- a/src/remote-config/remote-config.module.ts +++ b/src/remote-config/remote-config.module.ts @@ -1,20 +1,29 @@ -import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders } from '@angular/core'; +import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders, PLATFORM_ID, Injector } from '@angular/core'; import { RemoteConfig as FirebaseRemoteConfig } from 'firebase/remote-config'; -import { ɵmemoizeInstance, ɵgetDefaultInstanceOf, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; +import { ɵgetDefaultInstanceOf, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; import { RemoteConfig, RemoteConfigInstances, REMOTE_CONFIG_PROVIDER_NAME } from './remote-config'; import { FirebaseApps, FirebaseApp } from '@angular/fire/app'; import { registerVersion } from 'firebase/app'; +import { isPlatformBrowser } from '@angular/common'; export const PROVIDED_REMOTE_CONFIG_INSTANCES = new InjectionToken('angularfire2.remote-config-instances'); -export function defaultRemoteConfigInstanceFactory(provided: FirebaseRemoteConfig[]|undefined, defaultApp: FirebaseApp) { +export function defaultRemoteConfigInstanceFactory( + provided: FirebaseRemoteConfig[]|undefined, + defaultApp: FirebaseApp, + // tslint:disable-next-line:ban-types + platform: Object +) { + if (!isPlatformBrowser(platform)) { return null; } const defaultRemoteConfig = ɵgetDefaultInstanceOf(REMOTE_CONFIG_PROVIDER_NAME, provided, defaultApp); - return new RemoteConfig(defaultRemoteConfig); + return defaultRemoteConfig && new RemoteConfig(defaultRemoteConfig); } -export function remoteConfigInstanceFactory(fn: () => FirebaseRemoteConfig) { - return (zone: NgZone) => { - const remoteConfig = ɵmemoizeInstance(fn, zone); +export function remoteConfigInstanceFactory(fn: (injector: Injector) => FirebaseRemoteConfig) { + // tslint:disable-next-line:ban-types + return (zone: NgZone, platform: Object, injector: Injector) => { + if (!isPlatformBrowser(platform)) { return null; } + const remoteConfig = zone.runOutsideAngular(() => fn(injector)); return new RemoteConfig(remoteConfig); }; } @@ -32,6 +41,7 @@ const DEFAULT_REMOTE_CONFIG_INSTANCE_PROVIDER = { deps: [ [new Optional(), PROVIDED_REMOTE_CONFIG_INSTANCES ], FirebaseApp, + PLATFORM_ID, ] }; @@ -56,6 +66,8 @@ export function provideRemoteConfig(fn: () => FirebaseRemoteConfig): ModuleWithP multi: true, deps: [ NgZone, + PLATFORM_ID, + Injector, ɵAngularFireSchedulers, FirebaseApps, ] diff --git a/src/storage/storage.module.ts b/src/storage/storage.module.ts index b2c274bad..cb36f5273 100644 --- a/src/storage/storage.module.ts +++ b/src/storage/storage.module.ts @@ -1,6 +1,6 @@ -import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders } from '@angular/core'; +import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders, Injector } from '@angular/core'; import { FirebaseStorage } from 'firebase/storage'; -import { ɵgetDefaultInstanceOf, ɵmemoizeInstance, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; +import { ɵgetDefaultInstanceOf, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; import { Storage, StorageInstances, STORAGE_PROVIDER_NAME } from './storage'; import { FirebaseApps, FirebaseApp } from '@angular/fire/app'; import { AuthInstances } from '@angular/fire/auth'; @@ -10,13 +10,13 @@ import { AppCheckInstances } from '@angular/fire/app-check'; export const PROVIDED_STORAGE_INSTANCES = new InjectionToken('angularfire2.storage-instances'); export function defaultStorageInstanceFactory(provided: FirebaseStorage[]|undefined, defaultApp: FirebaseApp) { - const defaultAuth = ɵgetDefaultInstanceOf(STORAGE_PROVIDER_NAME, provided, defaultApp); - return new Storage(defaultAuth); + const defaultStorage = ɵgetDefaultInstanceOf(STORAGE_PROVIDER_NAME, provided, defaultApp); + return defaultStorage && new Storage(defaultStorage); } -export function storageInstanceFactory(fn: () => FirebaseStorage) { - return (zone: NgZone) => { - const storage = ɵmemoizeInstance(fn, zone); +export function storageInstanceFactory(fn: (injector: Injector) => FirebaseStorage) { + return (zone: NgZone, injector: Injector) => { + const storage = zone.runOutsideAngular(() => fn(injector)); return new Storage(storage); }; } @@ -58,6 +58,7 @@ export function provideStorage(fn: () => FirebaseStorage): ModuleWithProviders Date: Mon, 20 Sep 2021 08:41:30 -0400 Subject: [PATCH 2/7] Adding deps to the provide, flushing out sample/advanced to use it --- samples/advanced/package.json | 2 +- .../advanced/src/app/app.browser.module.ts | 5 -- samples/advanced/src/app/app.module.ts | 18 ++++++- samples/advanced/src/app/app.server.module.ts | 25 +++------ .../src/app/messaging/messaging.component.ts | 2 +- samples/advanced/yarn.lock | 17 ++++++ samples/compat/yarn.lock | 52 ++++++++++++++++--- src/analytics/analytics.module.ts | 3 +- src/app-check/app-check.module.ts | 3 +- src/app/app.module.ts | 5 +- src/auth/auth.module.ts | 3 +- src/database/database.module.ts | 3 +- src/firestore/firestore.module.ts | 3 +- src/functions/functions.module.ts | 3 +- src/messaging/messaging.module.ts | 3 +- src/performance/performance.module.ts | 3 +- src/remote-config/remote-config.module.ts | 3 +- src/storage/storage.module.ts | 3 +- 18 files changed, 112 insertions(+), 44 deletions(-) diff --git a/samples/advanced/package.json b/samples/advanced/package.json index 8746d1ba6..6034a1961 100644 --- a/samples/advanced/package.json +++ b/samples/advanced/package.json @@ -21,7 +21,7 @@ "@angular/common": "^12.0.0", "@angular/compiler": "^12.0.0", "@angular/core": "^12.0.0", - "@angular/fire": "../../angular-fire-7.1.0.tgz", + "@angular/fire": "../../dist/packages-dist", "@angular/forms": "^12.0.0", "@angular/platform-browser": "^12.0.0", "@angular/platform-browser-dynamic": "^12.0.0", diff --git a/samples/advanced/src/app/app.browser.module.ts b/samples/advanced/src/app/app.browser.module.ts index db674aae4..969f721af 100644 --- a/samples/advanced/src/app/app.browser.module.ts +++ b/samples/advanced/src/app/app.browser.module.ts @@ -12,7 +12,6 @@ import { BrowserTransferStateModule } from '@angular/platform-browser'; import { provideAuth } from '@angular/fire/auth'; import { initializeAuth, browserPopupRedirectResolver, indexedDBLocalPersistence } from '@angular/fire/auth'; -import { initializeAppCheck, provideAppCheck, ReCaptchaV3Provider } from '@angular/fire/app-check'; import { connectAuthEmulatorInDevMode } from './emulators'; @NgModule({ @@ -30,10 +29,6 @@ import { connectAuthEmulatorInDevMode } from './emulators'; connectAuthEmulatorInDevMode(auth); return auth; }), - provideAppCheck(() => { - const provider = new ReCaptchaV3Provider(environment.recaptcha3SiteKey); - return initializeAppCheck(undefined, { provider, isTokenAutoRefreshEnabled: true }); - }), ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production, registrationStrategy: 'registerWhenStable:30000' diff --git a/samples/advanced/src/app/app.module.ts b/samples/advanced/src/app/app.module.ts index 296a29361..0ca52a41f 100644 --- a/samples/advanced/src/app/app.module.ts +++ b/samples/advanced/src/app/app.module.ts @@ -1,7 +1,8 @@ -import { InjectionToken, NgModule } from '@angular/core'; +import { InjectionToken, NgModule, Optional } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { provideFirebaseApp, initializeApp } from '@angular/fire/app'; import { FunctionsModule } from '@angular/fire/functions'; +import { initializeAppCheck, provideAppCheck, ReCaptchaV3Provider, CustomProvider } from '@angular/fire/app-check'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @@ -40,6 +41,21 @@ export const FIREBASE_ADMIN = new InjectionToken('firebase-admin'); AppRoutingModule, FunctionsModule, provideFirebaseApp(() => initializeApp(environment.firebase)), + provideAppCheck((injector) => { + const admin = injector.get(FIREBASE_ADMIN, null); + if (admin) { + const provider = new CustomProvider({ getToken: () => + admin. + appCheck(). + createToken(environment.firebase.appId, { ttlMillis: 604_800_000, /* 1 week */ }). + then(({ token, ttlMillis: expireTimeMillis }) => ({ token, expireTimeMillis } )) + }); + return initializeAppCheck(undefined, { provider, isTokenAutoRefreshEnabled: false }); + } else { + const provider = new ReCaptchaV3Provider(environment.recaptcha3SiteKey); + return initializeAppCheck(undefined, { provider, isTokenAutoRefreshEnabled: true }); + } + }, [new Optional(), FIREBASE_ADMIN]), ], providers: [ ], bootstrap: [ ], diff --git a/samples/advanced/src/app/app.server.module.ts b/samples/advanced/src/app/app.server.module.ts index 9c305a712..e0a019be5 100644 --- a/samples/advanced/src/app/app.server.module.ts +++ b/samples/advanced/src/app/app.server.module.ts @@ -4,33 +4,22 @@ import * as admin from 'firebase-admin'; import { AppModule, FIREBASE_ADMIN } from './app.module'; import { AppComponent } from './app.component'; -import { initializeAppCheck, provideAppCheck, CustomProvider } from '@angular/fire/app-check'; import { environment } from 'src/environments/environment'; -const firebaseAdminApp = admin.apps[0] || admin.initializeApp( - // In Cloud Functions we can auto-initialize - process.env.FUNCTION_NAME ? undefined : { - credential: admin.credential.applicationDefault(), - databaseURL: environment.firebase.databaseURL, - } -); - -const appCheckToken = firebaseAdminApp.appCheck().createToken(environment.firebase.appId, { - ttlMillis: 604_800_000, // 1 week -}).then(({ token, ttlMillis: expireTimeMillis }) => ({ token, expireTimeMillis } )); - @NgModule({ imports: [ AppModule, ServerModule, ServerTransferStateModule, - provideAppCheck(() => { - const provider = new CustomProvider({ getToken: () => appCheckToken }); - return initializeAppCheck(undefined, { provider, isTokenAutoRefreshEnabled: false }); - }), ], providers: [ - { provide: FIREBASE_ADMIN, useValue: firebaseAdminApp } + { provide: FIREBASE_ADMIN, useFactory: () => admin.apps[0] || admin.initializeApp( + // In Cloud Functions we can auto-initialize + process.env.FUNCTION_NAME ? undefined : { + credential: admin.credential.applicationDefault(), + databaseURL: environment.firebase.databaseURL, + } + ) } ], bootstrap: [AppComponent], }) diff --git a/samples/advanced/src/app/messaging/messaging.component.ts b/samples/advanced/src/app/messaging/messaging.component.ts index d89e28c6e..6e617a809 100644 --- a/samples/advanced/src/app/messaging/messaging.component.ts +++ b/samples/advanced/src/app/messaging/messaging.component.ts @@ -22,7 +22,7 @@ export class MessagingComponent implements OnInit { message$: Observable = EMPTY; showRequest = false; - constructor(messaging: Messaging) { + constructor(@Optional() messaging: Messaging) { if (messaging) { this.token$ = from( navigator.serviceWorker.register('firebase-messaging-sw.js', { type: 'module', scope: '__' }). diff --git a/samples/advanced/yarn.lock b/samples/advanced/yarn.lock index 2534272c6..45a7ab7e4 100644 --- a/samples/advanced/yarn.lock +++ b/samples/advanced/yarn.lock @@ -262,6 +262,23 @@ tslib "^2.0.0" winston "^3.0.0" +"@angular/fire@../../dist/packages-dist": + version "7.1.0" + dependencies: + file-loader "^6.2.0" + fs-extra "^8.0.1" + fuzzy "^0.1.3" + inquirer "^8.1.1" + inquirer-autocomplete-prompt "^1.0.1" + jsonc-parser "^3.0.0" + node-fetch "^2.6.1" + open "^8.0.0" + ora "^5.3.0" + semver "^7.1.3" + triple-beam "^1.3.0" + tslib "^2.0.0" + winston "^3.0.0" + "@angular/forms@^12.0.0": version "12.2.5" resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-12.2.5.tgz#c190c1873ba856101323037147a0be906817bc82" diff --git a/samples/compat/yarn.lock b/samples/compat/yarn.lock index ab7149fe1..d1cfebed9 100644 --- a/samples/compat/yarn.lock +++ b/samples/compat/yarn.lock @@ -235,9 +235,21 @@ tslib "^2.2.0" "@angular/fire@../../dist/packages-dist": - version "7.0.4" + version "7.1.0" dependencies: + file-loader "^6.2.0" + fs-extra "^8.0.1" + fuzzy "^0.1.3" + inquirer "^8.1.1" + inquirer-autocomplete-prompt "^1.0.1" + jsonc-parser "^3.0.0" + node-fetch "^2.6.1" + open "^8.0.0" + ora "^5.3.0" + semver "^7.1.3" + triple-beam "^1.3.0" tslib "^2.0.0" + winston "^3.0.0" "@angular/forms@~12.2.2": version "12.2.5" @@ -5426,6 +5438,14 @@ figures@^3.0.0, figures@^3.2.0: dependencies: escape-string-regexp "^1.0.5" +file-loader@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + file-uri-to-path@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" @@ -5754,7 +5774,7 @@ fs-extra@^5.0.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^8.1.0: +fs-extra@^8.0.1, fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== @@ -6692,6 +6712,26 @@ inquirer@^6.2.2: strip-ansi "^5.1.0" through "^2.3.6" +inquirer@^8.1.1: + version "8.1.5" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.1.5.tgz#2dc5159203c826d654915b5fe6990fd17f54a150" + integrity sha512-G6/9xUqmt/r+UvufSyrPpt84NYwhKZ9jLsgMbQzlx804XErNupor8WQdBnBRrXmBfTPpuwf1sV+ss2ovjgdXIg== + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.1" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.21" + mute-stream "0.0.8" + ora "^5.4.1" + run-async "^2.4.0" + rxjs "^7.2.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + inquirer@~6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.3.1.tgz#7a413b5e7950811013a3db491c61d1f3b776e8e7" @@ -7509,7 +7549,7 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" -jsonc-parser@3.0.0: +jsonc-parser@3.0.0, jsonc-parser@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA== @@ -8933,7 +8973,7 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" -open@8.2.1: +open@8.2.1, open@^8.0.0: version "8.2.1" resolved "https://registry.yarnpkg.com/open/-/open-8.2.1.tgz#82de42da0ccbf429bc12d099dad2e0975e14e8af" integrity sha512-rXILpcQlkF/QuFez2BJDf3GsqpjGKbkUUToAIGo9A0Q6ZkoSGogZJulrUdwRkrAsoQvoZsrjCYt8+zblOk7JQQ== @@ -8992,7 +9032,7 @@ optionator@^0.8.1: type-check "~0.3.2" word-wrap "~1.2.3" -ora@5.4.1, ora@^5.1.0, ora@^5.3.0: +ora@5.4.1, ora@^5.1.0, ora@^5.3.0, ora@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== @@ -10739,7 +10779,7 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@7.3.5, semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: +semver@7.3.5, semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== diff --git a/src/analytics/analytics.module.ts b/src/analytics/analytics.module.ts index fe4a0653e..521e302fb 100644 --- a/src/analytics/analytics.module.ts +++ b/src/analytics/analytics.module.ts @@ -63,7 +63,7 @@ export class AnalyticsModule { } } -export function provideAnalytics(fn: (injector: Injector) => FirebaseAnalytics): ModuleWithProviders { +export function provideAnalytics(fn: (injector: Injector) => FirebaseAnalytics, ...deps: any[]): ModuleWithProviders { return { ngModule: AnalyticsModule, providers: [{ @@ -79,6 +79,7 @@ export function provideAnalytics(fn: (injector: Injector) => FirebaseAnalytics): Injector, ɵAngularFireSchedulers, FirebaseApps, + ...deps, ] }] }; diff --git a/src/app-check/app-check.module.ts b/src/app-check/app-check.module.ts index a0a131ba0..0a1c6cc7b 100644 --- a/src/app-check/app-check.module.ts +++ b/src/app-check/app-check.module.ts @@ -56,7 +56,7 @@ export class AppCheckModule { } } -export function provideAppCheck(fn: (injector: Injector) => FirebaseAppCheck): ModuleWithProviders { +export function provideAppCheck(fn: (injector: Injector) => FirebaseAppCheck, ...deps: any[]): ModuleWithProviders { return { ngModule: AppCheckModule, providers: [{ @@ -68,6 +68,7 @@ export function provideAppCheck(fn: (injector: Injector) => FirebaseAppCheck): M Injector, ɵAngularFireSchedulers, FirebaseApps, + ...deps, ] }] }; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 31e087acf..2cdfad94f 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -68,7 +68,7 @@ export class FirebaseAppModule { // Calling initializeApp({ ... }, 'name') multiple times will add more FirebaseApps into the FIREBASE_APPS // injection scope. This allows developers to more easily work with multiple Firebase Applications. Downside // is that DI for app name and options doesn't really make sense anymore. -export function provideFirebaseApp(fn: () => IFirebaseApp): ModuleWithProviders { +export function provideFirebaseApp(fn: () => IFirebaseApp, ...deps: any[]): ModuleWithProviders { return { ngModule: FirebaseAppModule, providers: [{ @@ -78,7 +78,8 @@ export function provideFirebaseApp(fn: () => IFirebaseApp): ModuleWithProviders< deps: [ NgZone, Injector, - ɵAngularFireSchedulers + ɵAngularFireSchedulers, + ...deps, ], }], }; diff --git a/src/auth/auth.module.ts b/src/auth/auth.module.ts index d6e61b35a..84aad8409 100644 --- a/src/auth/auth.module.ts +++ b/src/auth/auth.module.ts @@ -48,7 +48,7 @@ export class AuthModule { } } -export function provideAuth(fn: () => FirebaseAuth): ModuleWithProviders { +export function provideAuth(fn: () => FirebaseAuth, ...deps: any[]): ModuleWithProviders { return { ngModule: AuthModule, providers: [{ @@ -61,6 +61,7 @@ export function provideAuth(fn: () => FirebaseAuth): ModuleWithProviders FirebaseDatabase): ModuleWithProviders { +export function provideDatabase(fn: () => FirebaseDatabase, ...deps: any[]): ModuleWithProviders { return { ngModule: DatabaseModule, providers: [{ @@ -64,6 +64,7 @@ export function provideDatabase(fn: () => FirebaseDatabase): ModuleWithProviders // Database+Auth work better if Auth is loaded first [new Optional(), AuthInstances ], [new Optional(), AppCheckInstances ], + ...deps, ] }] }; diff --git a/src/firestore/firestore.module.ts b/src/firestore/firestore.module.ts index 6ba571f78..9b5e6858e 100644 --- a/src/firestore/firestore.module.ts +++ b/src/firestore/firestore.module.ts @@ -49,7 +49,7 @@ export class FirestoreModule { } } -export function provideFirestore(fn: () => FirebaseFirestore): ModuleWithProviders { +export function provideFirestore(fn: () => FirebaseFirestore, ...deps: any[]): ModuleWithProviders { return { ngModule: FirestoreModule, providers: [{ @@ -64,6 +64,7 @@ export function provideFirestore(fn: () => FirebaseFirestore): ModuleWithProvide // Firestore+Auth work better if Auth is loaded first [new Optional(), AuthInstances ], [new Optional(), AppCheckInstances ], + ...deps, ] }] }; diff --git a/src/functions/functions.module.ts b/src/functions/functions.module.ts index 9cd0354c1..00784eaea 100644 --- a/src/functions/functions.module.ts +++ b/src/functions/functions.module.ts @@ -49,7 +49,7 @@ export class FunctionsModule { } } -export function provideFunctions(fn: () => FirebaseFunctions): ModuleWithProviders { +export function provideFunctions(fn: () => FirebaseFunctions, ...deps: any[]): ModuleWithProviders { return { ngModule: FunctionsModule, providers: [{ @@ -64,6 +64,7 @@ export function provideFunctions(fn: () => FirebaseFunctions): ModuleWithProvide // Defensively load Auth first, if provided [new Optional(), AuthInstances ], [new Optional(), AppCheckInstances ], + ...deps, ] }] }; diff --git a/src/messaging/messaging.module.ts b/src/messaging/messaging.module.ts index 5ed8863dd..2d2b60552 100644 --- a/src/messaging/messaging.module.ts +++ b/src/messaging/messaging.module.ts @@ -58,7 +58,7 @@ export class MessagingModule { } } -export function provideMessaging(fn: () => FirebaseMessaging): ModuleWithProviders { +export function provideMessaging(fn: () => FirebaseMessaging, ...deps: any[]): ModuleWithProviders { return { ngModule: MessagingModule, providers: [{ @@ -74,6 +74,7 @@ export function provideMessaging(fn: () => FirebaseMessaging): ModuleWithProvide Injector, ɵAngularFireSchedulers, FirebaseApps, + ...deps, ], }] }; diff --git a/src/performance/performance.module.ts b/src/performance/performance.module.ts index 106806fbb..a7aa08680 100644 --- a/src/performance/performance.module.ts +++ b/src/performance/performance.module.ts @@ -57,7 +57,7 @@ export class PerformanceModule { } } -export function providePerformance(fn: () => FirebasePerformance): ModuleWithProviders { +export function providePerformance(fn: () => FirebasePerformance, ...deps: any[]): ModuleWithProviders { return { ngModule: PerformanceModule, providers: [{ @@ -70,6 +70,7 @@ export function providePerformance(fn: () => FirebasePerformance): ModuleWithPro Injector, ɵAngularFireSchedulers, FirebaseApps, + ...deps, ] }] }; diff --git a/src/remote-config/remote-config.module.ts b/src/remote-config/remote-config.module.ts index d50b65433..d9319bc05 100644 --- a/src/remote-config/remote-config.module.ts +++ b/src/remote-config/remote-config.module.ts @@ -57,7 +57,7 @@ export class RemoteConfigModule { } } -export function provideRemoteConfig(fn: () => FirebaseRemoteConfig): ModuleWithProviders { +export function provideRemoteConfig(fn: () => FirebaseRemoteConfig, ...deps: any[]): ModuleWithProviders { return { ngModule: RemoteConfigModule, providers: [{ @@ -70,6 +70,7 @@ export function provideRemoteConfig(fn: () => FirebaseRemoteConfig): ModuleWithP Injector, ɵAngularFireSchedulers, FirebaseApps, + ...deps, ] }] }; diff --git a/src/storage/storage.module.ts b/src/storage/storage.module.ts index cb36f5273..09f523941 100644 --- a/src/storage/storage.module.ts +++ b/src/storage/storage.module.ts @@ -49,7 +49,7 @@ export class StorageModule { } } -export function provideStorage(fn: () => FirebaseStorage): ModuleWithProviders { +export function provideStorage(fn: () => FirebaseStorage, ...deps: any[]): ModuleWithProviders { return { ngModule: StorageModule, providers: [{ @@ -64,6 +64,7 @@ export function provideStorage(fn: () => FirebaseStorage): ModuleWithProviders Date: Tue, 5 Oct 2021 20:21:41 -0400 Subject: [PATCH 3/7] Bumping to Firebase 9.1 and using remote-config isSupported --- package.json | 2 +- samples/advanced/yarn.lock | 588 ++++++++++++---------- src/compat/remote-config/remote-config.ts | 6 +- src/remote-config/firebase.ts | 2 + src/remote-config/remote-config.module.ts | 30 +- tools/build.ts | 3 + yarn.lock | 510 ++++++++++--------- 7 files changed, 615 insertions(+), 526 deletions(-) diff --git a/package.json b/package.json index a0cc673eb..0ae9619d4 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "@angular/platform-browser-dynamic": "^12.0.0", "@angular/router": "^12.0.0", "@schematics/angular": "^12.0.0", - "firebase": "^9.0.0", + "firebase": "^9.1.0", "firebase-admin": "^9.11.1", "firebase-functions": "^3.6.0", "firebase-tools": "^9.0.0", diff --git a/samples/advanced/yarn.lock b/samples/advanced/yarn.lock index 45a7ab7e4..d4202c3bf 100644 --- a/samples/advanced/yarn.lock +++ b/samples/advanced/yarn.lock @@ -244,24 +244,6 @@ dependencies: tslib "^2.2.0" -"@angular/fire@../../angular-fire-7.1.0.tgz": - version "7.1.0" - resolved "../../angular-fire-7.1.0.tgz#749a0443e5974789fbdc5a3b31237aa6506d7b7e" - dependencies: - file-loader "^6.2.0" - fs-extra "^8.0.1" - fuzzy "^0.1.3" - inquirer "^8.1.1" - inquirer-autocomplete-prompt "^1.0.1" - jsonc-parser "^3.0.0" - node-fetch "^2.6.1" - open "^8.0.0" - ora "^5.3.0" - semver "^7.1.3" - triple-beam "^1.3.0" - tslib "^2.0.0" - winston "^3.0.0" - "@angular/fire@../../dist/packages-dist": version "7.1.0" dependencies: @@ -1287,15 +1269,15 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz#90420f9f9c6d3987f176a19a7d8e764271a2f55d" integrity sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g== -"@firebase/analytics-compat@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@firebase/analytics-compat/-/analytics-compat-0.1.1.tgz#77a3e5d28f15df303c3836db4740a43955fcfcac" - integrity sha512-pMTrA8cxMXFRv7bwZEXXz0NCepnyH2Jay/32RZ7xAufij2VJhF5S1BtfCO0wuri3FB94rlM8SmSEbwxxHcAtVg== +"@firebase/analytics-compat@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@firebase/analytics-compat/-/analytics-compat-0.1.2.tgz#db115aabf1b30b43567e45cca86f3856aafb93b4" + integrity sha512-TpWpz0s8EgVt9aqyOCFktONqVkjyrNRR4esn3cEYrueH+XXSMDLWY9oFHuUJzntcoEOlOBWMvpsJCPG/1kthkg== dependencies: - "@firebase/analytics" "0.7.0" + "@firebase/analytics" "0.7.1" "@firebase/analytics-types" "0.7.0" - "@firebase/component" "0.5.6" - "@firebase/util" "1.3.0" + "@firebase/component" "0.5.7" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/analytics-types@0.7.0": @@ -1303,26 +1285,26 @@ resolved "https://registry.yarnpkg.com/@firebase/analytics-types/-/analytics-types-0.7.0.tgz#91960e7c87ce8bf18cf8dd9e55ccbf5dc3989b5d" integrity sha512-DNE2Waiwy5+zZnCfintkDtBfaW6MjIG883474v6Z0K1XZIvl76cLND4iv0YUb48leyF+PJK1KO2XrgHb/KpmhQ== -"@firebase/analytics@0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@firebase/analytics/-/analytics-0.7.0.tgz#7f4450936a2cac3227cc6439130c09b9a0a7d83e" - integrity sha512-YEPyeW6CV8xbIvWaJMvfRdWUPKe/xchJ1bjV6GpLfkYRX+ZE1/YSNU14pX292M4bZ6Qg+bbu2DuWp8fEpa/YQg== +"@firebase/analytics@0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@firebase/analytics/-/analytics-0.7.1.tgz#e95cf81ffc748fc73422eed081d4dd8e1e5f1e0c" + integrity sha512-fTUN47UK4obzIJwmgLMJU46dWZ7pzitCEO+80pQZC7mdLlVs/NW0+tMf6rETwMpKjGSgb25cKidpgEuioQtT7w== dependencies: - "@firebase/component" "0.5.6" - "@firebase/installations" "0.5.0" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" + "@firebase/component" "0.5.7" + "@firebase/installations" "0.5.1" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" -"@firebase/app-check-compat@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@firebase/app-check-compat/-/app-check-compat-0.1.1.tgz#84c7ef29bb683fd3dea66a66f82b799474c904ee" - integrity sha512-XTV5Ns0Lpwn5GgXV5T0soOkoOGACaw9xiNvAXcISQYFBIse0k7fKo8V5J9VUS1ppzGpyTRCg0m9efz4CNrwPyQ== +"@firebase/app-check-compat@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@firebase/app-check-compat/-/app-check-compat-0.1.2.tgz#1e5480a9f83c1cec814b3a11032a797b1a50eaec" + integrity sha512-JB+OHk4Cp9ZgT+UfX0A+lwH1AoM5Y2X1rDhmhCsEXcKKwz1w9DpL9PjStciP8UYg1dpqbp5p9OMxmty+21EBsA== dependencies: - "@firebase/app-check" "0.4.0" - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" + "@firebase/app-check" "0.4.1" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/app-check-interop-types@0.1.0": @@ -1330,25 +1312,25 @@ resolved "https://registry.yarnpkg.com/@firebase/app-check-interop-types/-/app-check-interop-types-0.1.0.tgz#83afd9d41f99166c2bdb2d824e5032e9edd8fe53" integrity sha512-uZfn9s4uuRsaX5Lwx+gFP3B6YsyOKUE+Rqa6z9ojT4VSRAsZFko9FRn6OxQUA1z5t5d08fY4pf+/+Dkd5wbdbA== -"@firebase/app-check@0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@firebase/app-check/-/app-check-0.4.0.tgz#a048fc396b2a97ef8eba77fe909efbff07a5c75c" - integrity sha512-KQ/k8cukzZbH/LC9Iu5/Dbhr7w6byu8bYjfCA38B6v8aISgASYfP/nirxRD+hSuDoxXtAnPGEuv+v0YU3D1R2w== +"@firebase/app-check@0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@firebase/app-check/-/app-check-0.4.1.tgz#60e329b3871574a0431536edca69e0d0a8cbd674" + integrity sha512-Kpqh0Y2zpx+acTL7eOVYIWBOmAwoconJpqOAlByGNXuxm/ccP00XREo+HsqaC7wapZRXh+h8BK0jZjvdV36qow== dependencies: - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" -"@firebase/app-compat@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.1.1.tgz#47d5f5ac350f59ea4b721f17e01b1e46a1a3154a" - integrity sha512-AoUO7PnQlDPyMAvAE972kBhrwXRZRLGdHM8obyIeTzPNqIiEoULD4Rdq5TBB4UmV2HYAlYdrS+dk4nuWx67w6A== +"@firebase/app-compat@0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.1.3.tgz#4757c8f65d2a067d24afdfef4f736a5f53c66656" + integrity sha512-+/U2RgRLfLznPuluIMW3bsAehTBTVWKxA6l6jjk9noozPuP99xOulReMqf5kCrXVdW1aMHdRuKfntjbTAR8+aw== dependencies: - "@firebase/app" "0.7.0" - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" + "@firebase/app" "0.7.2" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/app-types@0.6.3": @@ -1361,26 +1343,26 @@ resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.7.0.tgz#c9e16d1b8bed1a991840b8d2a725fb58d0b5899f" integrity sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg== -"@firebase/app@0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.7.0.tgz#989e9f354951de2a8ac806f6e3fa0afd9f80b470" - integrity sha512-l4Pd69re6JyjumQrl719dnY5JSKROSYda/0N2wzOhSzqg8DsZOIErr8+xj6QAE6BtNsoIEk7ma9WMS/2r02MhA== +"@firebase/app@0.7.2": + version "0.7.2" + resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.7.2.tgz#0df26d6e9861d5ebe038d4e1f10b63111a28a1f7" + integrity sha512-xKO3KWxVqCLijJToaBGvBnXCaVGvIw+rT2Dtd9B2iyOFJieQQ+xx8/zRWgoSqbMBIZ2crQVr0KdsoyP9D2nQfg== dependencies: - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" -"@firebase/auth-compat@0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@firebase/auth-compat/-/auth-compat-0.1.2.tgz#a971cb7859eb4d45c233043bea102993376d9fca" - integrity sha512-0eqWSV4XoyOltT4HVJUzh8hBFNO5f78ZGDplRQImQ97/6wR45x6Q/9R19KTWOd109+3Axw6Orfq2cSNY0opgEA== +"@firebase/auth-compat@0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@firebase/auth-compat/-/auth-compat-0.1.4.tgz#d55084f0d37086d58a1da4748c9bbec2ede0a80a" + integrity sha512-Vn7Dsxa7B50ihgDAMQAVb/IxU9tcQyR1JDbWjZzf2b1212hBuuwEs1V1u01xoKunMXMSg+P8ztbG7IRxOj2FdQ== dependencies: - "@firebase/auth" "0.17.2" + "@firebase/auth" "0.18.1" "@firebase/auth-types" "0.11.0" - "@firebase/component" "0.5.6" - "@firebase/util" "1.3.0" - node-fetch "2.6.1" + "@firebase/component" "0.5.7" + "@firebase/util" "1.4.0" + node-fetch "2.6.5" selenium-webdriver "^4.0.0-beta.2" tslib "^2.1.0" @@ -1394,16 +1376,16 @@ resolved "https://registry.yarnpkg.com/@firebase/auth-types/-/auth-types-0.11.0.tgz#b9c73c60ca07945b3bbd7a097633e5f78fa9e886" integrity sha512-q7Bt6cx+ySj9elQHTsKulwk3+qDezhzRBFC9zlQ1BjgMueUOnGMcvqmU0zuKlQ4RhLSH7MNAdBV2znVaoN3Vxw== -"@firebase/auth@0.17.2": - version "0.17.2" - resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-0.17.2.tgz#54ad76cfdc2f6d1201fb780365cf7d362586f3c6" - integrity sha512-t1iHB5Eg7vAbyOEzMMarsyJNGiO2xP8Zag0hLRVXWVaWymXZnyVKp62sXqyonvz4eVT8+iGBjDySB9zKIb5Pqg== +"@firebase/auth@0.18.1": + version "0.18.1" + resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-0.18.1.tgz#2cba86c5ac614aea8ea1bdc55e479530c187b5ce" + integrity sha512-q455ls7Hjug3yGp7htLL/LABqySoXGXL/ADLJPyiSnVl22a5oQWuTKUL6N5PAXHc5LwygFfHYiHrNhpQDaGm3w== dependencies: - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" - node-fetch "2.6.1" - selenium-webdriver "4.0.0-beta.1" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" + node-fetch "2.6.5" + selenium-webdriver "4.0.0-rc-1" tslib "^2.1.0" "@firebase/component@0.5.5": @@ -1414,24 +1396,24 @@ "@firebase/util" "1.2.0" tslib "^2.1.0" -"@firebase/component@0.5.6": - version "0.5.6" - resolved "https://registry.yarnpkg.com/@firebase/component/-/component-0.5.6.tgz#6b7c7aff69866e0925721543a2ef5f47b0f97cbe" - integrity sha512-GyQJ+2lrhsDqeGgd1VdS7W+Y6gNYyI0B51ovNTxeZVG/W8I7t9MwEiCWsCvfm5wQgfsKp9dkzOcJrL5k8oVO/Q== +"@firebase/component@0.5.7": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@firebase/component/-/component-0.5.7.tgz#a50c5fbd14a2136a99ade6f59f53498729c0f174" + integrity sha512-CiAHUPXh2hn/lpzMShNmfAxHNQhKQwmQUJSYMPCjf2bCCt4Z2vLGpS+UWEuNFm9Zf8LNmkS+Z+U/s4Obi5carg== dependencies: - "@firebase/util" "1.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" -"@firebase/database-compat@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@firebase/database-compat/-/database-compat-0.1.0.tgz#f02abaa9f493fd14aaae6e2b34262bafc5d033c7" - integrity sha512-jLN0JMYnYijg8f3QFtSuPGNuKAt3yYVRsHHlR8sADgx8MptByRRwVmMOk7QPc/DY7qscZIJow3hXFwvbeApFLA== - dependencies: - "@firebase/component" "0.5.6" - "@firebase/database" "0.12.0" - "@firebase/database-types" "0.9.0" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" +"@firebase/database-compat@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@firebase/database-compat/-/database-compat-0.1.1.tgz#9fe69e3bd3f71d29011bb6ca793f38edb65ca536" + integrity sha512-K3DFWiw0YkLZtlfA9TOGPw6zVXKu5dQ1XqIGztUufFVRYW8IizReXVxzSSmJNR4Adr2LiU9j66Wenc6e5UfwaQ== + dependencies: + "@firebase/component" "0.5.7" + "@firebase/database" "0.12.1" + "@firebase/database-types" "0.9.1" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/database-types@0.7.3", "@firebase/database-types@^0.7.2": @@ -1441,24 +1423,24 @@ dependencies: "@firebase/app-types" "0.6.3" -"@firebase/database-types@0.9.0": - version "0.9.0" - resolved "https://registry.yarnpkg.com/@firebase/database-types/-/database-types-0.9.0.tgz#dad3db745531f40b60f7726a76b2bf6bbf6c6471" - integrity sha512-x2TeTVnMZGPvT3y4Nayio4WprQA/zGwqMrPMQwSdF+PFnaFJAhA/eLgUB6cmWFzFYO9VvmuRkFzDzo6ezTo1Zw== +"@firebase/database-types@0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@firebase/database-types/-/database-types-0.9.1.tgz#0cab989e8154d812b535d80f23c1578b1d391f5f" + integrity sha512-RUixK/YrbpxbfdE+nYP0wMcEsz1xPTnafP0q3UlSS/+fW744OITKtR1J0cMRaXbvY7EH0wUVTNVkrtgxYY8IgQ== dependencies: "@firebase/app-types" "0.7.0" - "@firebase/util" "1.3.0" + "@firebase/util" "1.4.0" -"@firebase/database@0.12.0": - version "0.12.0" - resolved "https://registry.yarnpkg.com/@firebase/database/-/database-0.12.0.tgz#2aa33138128cfcaf74388efe13e0eda10825d564" - integrity sha512-/gl6z6fAxAAFAdDllzidzweGpuXJu0b9AusSLrdW4LpP6KCuxJbhonMJuSGpHLzAHzx6Q9uitbvqHqBb17sttQ== +"@firebase/database@0.12.1": + version "0.12.1" + resolved "https://registry.yarnpkg.com/@firebase/database/-/database-0.12.1.tgz#7e43f27ac4057858d5bd0dd371b134b304fecdb0" + integrity sha512-Ethk0hc476qnkSKNBa+8Yc7iM8AO69HYWsaD+QUC983FZtnuMyNLHtEeSUbLQYvyHo7cOjcc52slop14WmfZeQ== dependencies: "@firebase/auth-interop-types" "0.1.6" - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" - faye-websocket "0.11.3" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" + faye-websocket "0.11.4" tslib "^2.1.0" "@firebase/database@^0.10.0": @@ -1474,15 +1456,15 @@ faye-websocket "0.11.3" tslib "^2.1.0" -"@firebase/firestore-compat@0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@firebase/firestore-compat/-/firestore-compat-0.1.2.tgz#af9e28735376ee04c147ea3ac11b592b3f7a68ac" - integrity sha512-xtjj2qOBN0+S5KlXmWa5UozGmYJ1OAGBNT0qkCSvzQitHED5/B2fNwKnpy7Em+Zu3Yc3r/eM94OGx93USFXifg== +"@firebase/firestore-compat@0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@firebase/firestore-compat/-/firestore-compat-0.1.3.tgz#a898f6819b9d87134b5e09fcf9b2fb5bfc0ee68b" + integrity sha512-tO3uAkIguKeFeKPu99GR7F7v1/Hc8nV1h7B1kdpkVRRBe+NfVYA3qAUictQ3OAA0oy7Ae9z4SfEURO/R1b6YlQ== dependencies: - "@firebase/component" "0.5.6" - "@firebase/firestore" "3.0.2" + "@firebase/component" "0.5.7" + "@firebase/firestore" "3.1.0" "@firebase/firestore-types" "2.5.0" - "@firebase/util" "1.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/firestore-types@2.5.0": @@ -1490,29 +1472,29 @@ resolved "https://registry.yarnpkg.com/@firebase/firestore-types/-/firestore-types-2.5.0.tgz#16fca40b6980fdb000de86042d7a96635f2bcdd7" integrity sha512-I6c2m1zUhZ5SH0cWPmINabDyH5w0PPFHk2UHsjBpKdZllzJZ2TwTkXbDtpHUZNmnc/zAa0WNMNMvcvbb/xJLKA== -"@firebase/firestore@3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@firebase/firestore/-/firestore-3.0.2.tgz#594130bb125803b6e28611075c2f396f59ba8186" - integrity sha512-AWh1pugDifwCXHaQalZHp+Hr/3o+cxYvlbgQrPB35bh1A3do4I1xim/8Pba7gtpTzlClDryd5pK/XbK0TC/2kg== +"@firebase/firestore@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@firebase/firestore/-/firestore-3.1.0.tgz#0a59e41f164b28116aca1a264acef0dbc8e5a585" + integrity sha512-vOXueHNRjlgBlKVCWuUDhr3dQW2hJwbcqcJaFiIV9V+PamfyhOHzX8pEQkrPort4YQQvoRmY9uiFhfOGj2hbeA== dependencies: - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" - "@firebase/webchannel-wrapper" "0.5.1" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" + "@firebase/webchannel-wrapper" "0.6.0" "@grpc/grpc-js" "^1.3.2" "@grpc/proto-loader" "^0.6.0" - node-fetch "2.6.1" + node-fetch "2.6.2" tslib "^2.1.0" -"@firebase/functions-compat@0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@firebase/functions-compat/-/functions-compat-0.1.2.tgz#557461ed4f2928747461c6b2d246ac328aea3248" - integrity sha512-eisJazUrqOL/pAZJPqamYiaAyV3ch6GQMx8Sso792tvRr8SFsNCFbN9eVun0U0ubWAON5qdLoruoc6npXg6FIg== +"@firebase/functions-compat@0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@firebase/functions-compat/-/functions-compat-0.1.3.tgz#19758884bf41752102bd0a420be2aa49ee2d45de" + integrity sha512-NdobePNq5LUHCI1dJHUGlOTw+Qmq/FJre981/ELEMBdEs95kmKwnXB2UaLjAQYWkgkr4YS3lEnNpsiSTaEHFCg== dependencies: - "@firebase/component" "0.5.6" - "@firebase/functions" "0.7.1" + "@firebase/component" "0.5.7" + "@firebase/functions" "0.7.2" "@firebase/functions-types" "0.5.0" - "@firebase/util" "1.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/functions-types@0.5.0": @@ -1520,26 +1502,26 @@ resolved "https://registry.yarnpkg.com/@firebase/functions-types/-/functions-types-0.5.0.tgz#b50ba95ccce9e96f7cda453228ffe1684645625b" integrity sha512-qza0M5EwX+Ocrl1cYI14zoipUX4gI/Shwqv0C1nB864INAD42Dgv4v94BCyxGHBg2kzlWy8PNafdP7zPO8aJQA== -"@firebase/functions@0.7.1": - version "0.7.1" - resolved "https://registry.yarnpkg.com/@firebase/functions/-/functions-0.7.1.tgz#aa95aaed34649d0656d50df0ed21802f117cca88" - integrity sha512-F6XZVVBpqupCX7/YXpdzyXKYCeLVmHO/jxAKbN9I4B+c8doDqVtGkO23DPzf4ppzR4FuXDiKEEU9ZZ85kqZ1QA== +"@firebase/functions@0.7.2": + version "0.7.2" + resolved "https://registry.yarnpkg.com/@firebase/functions/-/functions-0.7.2.tgz#9628afb88c0c9d302969b4dd37f09010b18c43f4" + integrity sha512-B+b57xXtpsRYD3UgVtteeyavXjXfBTtuv+sG8LA0vgJs6bhORswVlKZQqpfW9SDxCMBwzzytzn1m3ZZGfUw2Lg== dependencies: "@firebase/app-check-interop-types" "0.1.0" "@firebase/auth-interop-types" "0.1.6" - "@firebase/component" "0.5.6" + "@firebase/component" "0.5.7" "@firebase/messaging-interop-types" "0.1.0" - "@firebase/util" "1.3.0" - node-fetch "2.6.1" + "@firebase/util" "1.4.0" + node-fetch "2.6.2" tslib "^2.1.0" -"@firebase/installations@0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@firebase/installations/-/installations-0.5.0.tgz#4a21e1c7467795802b031af413df2555b17cf1b1" - integrity sha512-wF1CKIx+SoiEbtNdutulxW4z80B5lGXW+8JdAtcKQwgKxF0VtlCaDFsd9AEB3aTtzIve5UkGak8hQOMvvOpydg== +"@firebase/installations@0.5.1": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@firebase/installations/-/installations-0.5.1.tgz#3c515494fad8fba552ae0f01c675219e29e218e2" + integrity sha512-KZ1XHrEPmCx3Z70P9d8mHmYEZXA/uiLIkV0D8R45Q65c0DUxBDm5tSQs56QWofxB/wx16xmO3xAZw4BdJUBnlQ== dependencies: - "@firebase/component" "0.5.6" - "@firebase/util" "1.3.0" + "@firebase/component" "0.5.7" + "@firebase/util" "1.4.0" idb "3.0.2" tslib "^2.1.0" @@ -1548,14 +1530,21 @@ resolved "https://registry.yarnpkg.com/@firebase/logger/-/logger-0.2.6.tgz#3aa2ca4fe10327cabf7808bd3994e88db26d7989" integrity sha512-KIxcUvW/cRGWlzK9Vd2KB864HlUnCfdTH0taHE0sXW5Xl7+W68suaeau1oKNEqmc3l45azkd4NzXTCWZRZdXrw== -"@firebase/messaging-compat@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@firebase/messaging-compat/-/messaging-compat-0.1.0.tgz#ab164540f6ba954c8d150b2e96dc6bf8c1536eb4" - integrity sha512-58qQmKwOiXhxZwrRwwjQDbjlRx1uMVVuV/DNbDzqilDJDdoYXMdK6RBTF9Bs51qy/Z1BI2Q9B1JX01QYlgZpxQ== +"@firebase/logger@0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@firebase/logger/-/logger-0.3.0.tgz#a3992e40f62c10276dbfcb8b4ab376b7e25d7fd9" + integrity sha512-7oQ+TctqekfgZImWkKuda50JZfkmAKMgh5qY4aR4pwRyqZXuJXN1H/BKkHvN1y0S4XWtF0f/wiCLKHhyi1ppPA== + dependencies: + tslib "^2.1.0" + +"@firebase/messaging-compat@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@firebase/messaging-compat/-/messaging-compat-0.1.1.tgz#aef5045cc30c781e33aa9030e26feca3f7aedda4" + integrity sha512-8FxrQjJCOfP9HibFsymT3qB18rBBmMPxOV+k0n6B7L6KW6Idswq01hMW12d93ZnvlNNKdikCKwUtBNbITBd8FA== dependencies: - "@firebase/component" "0.5.6" - "@firebase/messaging" "0.9.0" - "@firebase/util" "1.3.0" + "@firebase/component" "0.5.7" + "@firebase/messaging" "0.9.1" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/messaging-interop-types@0.1.0": @@ -1563,28 +1552,28 @@ resolved "https://registry.yarnpkg.com/@firebase/messaging-interop-types/-/messaging-interop-types-0.1.0.tgz#bdac02dd31edd5cb9eec37b1db698ea5e2c1a631" integrity sha512-DbvUl/rXAZpQeKBnwz0NYY5OCqr2nFA0Bj28Fmr3NXGqR4PAkfTOHuQlVtLO1Nudo3q0HxAYLa68ZDAcuv2uKQ== -"@firebase/messaging@0.9.0": - version "0.9.0" - resolved "https://registry.yarnpkg.com/@firebase/messaging/-/messaging-0.9.0.tgz#a868bea75d0c26210903178cf22d31c47bc84584" - integrity sha512-NTUB+gVJsgL/f6wqwUlgadaNuLZvyk1IlTcRvR3391t8jDSWOT2efwzNqcI7Xv4nhzaiPhzAQ4ncH/m8kfUUXQ== +"@firebase/messaging@0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@firebase/messaging/-/messaging-0.9.1.tgz#4403dc5fdb2193818cecc359a4b31504c2cd5ac8" + integrity sha512-0g3JWTfkv0WHnu4xgx1zcChJXU2dLjWT0e2MI13Q7NbP3TgLu5CgQ/H/lad16j4Zb4RNqZbAUJurEAB6v2BJ/w== dependencies: - "@firebase/component" "0.5.6" - "@firebase/installations" "0.5.0" + "@firebase/component" "0.5.7" + "@firebase/installations" "0.5.1" "@firebase/messaging-interop-types" "0.1.0" - "@firebase/util" "1.3.0" + "@firebase/util" "1.4.0" idb "3.0.2" tslib "^2.1.0" -"@firebase/performance-compat@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@firebase/performance-compat/-/performance-compat-0.1.0.tgz#c1edeccd9b60d83de26d8e645e0d2ddd64e9a2d7" - integrity sha512-H+/A5+y/15hFn5FHRP8lcogDzO6qm9YoACNEXn71UN4PiGQ+/BbHkQafDEXxD6wLfqfqR8u8oclHPFIYxMBF7Q== +"@firebase/performance-compat@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@firebase/performance-compat/-/performance-compat-0.1.1.tgz#c895aaa57a08b3b9be035de764ccad4b02cb4e52" + integrity sha512-xN/TjU0hVNiJshZzrUvPYB+3sPS9SgaWrfxh3p0eGFVdwHp/3Z8HlT772bkHAEKXVc64v19ktpUVd+sF5aoJNQ== dependencies: - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/performance" "0.5.0" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/performance" "0.5.1" "@firebase/performance-types" "0.1.0" - "@firebase/util" "1.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/performance-types@0.1.0": @@ -1592,15 +1581,15 @@ resolved "https://registry.yarnpkg.com/@firebase/performance-types/-/performance-types-0.1.0.tgz#5e6efa9dc81860aee2cb7121b39ae8fa137e69fc" integrity sha512-6p1HxrH0mpx+622Ql6fcxFxfkYSBpE3LSuwM7iTtYU2nw91Hj6THC8Bc8z4nboIq7WvgsT/kOTYVVZzCSlXl8w== -"@firebase/performance@0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@firebase/performance/-/performance-0.5.0.tgz#cc237e65791c75dba856ace8971b94d7adcbc60b" - integrity sha512-E+L18eJKshr/ijnWZMexEEddwkp2T4Ye2dJSK4TcOKRYfrmfZJ95RRZ+MPNp1ES7RH2JYiyym1NIQKPcNNvhug== +"@firebase/performance@0.5.1": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@firebase/performance/-/performance-0.5.1.tgz#bb38ce1d98faba4e1c88530cc2af53cfecb58b7e" + integrity sha512-O93Yry8KhAaFrhnmBaMkM0lpgVmpd7CRX0eq1S0IKLdE3MdF+oAtbQiZG/NuRl3Vz8vjoz96R6bPbCWaDuiy8Q== dependencies: - "@firebase/component" "0.5.6" - "@firebase/installations" "0.5.0" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" + "@firebase/component" "0.5.7" + "@firebase/installations" "0.5.1" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/polyfill@0.3.36": @@ -1612,16 +1601,16 @@ promise-polyfill "8.1.3" whatwg-fetch "2.0.4" -"@firebase/remote-config-compat@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@firebase/remote-config-compat/-/remote-config-compat-0.1.0.tgz#8eb2582d1909dd4d5023383e43d73ad605d56daa" - integrity sha512-PpCh5f5hUUaDCmiJsuu/u9a0g0G5WH3YSbfH1jPejVOaJ1lS82615E7WOzco4zMllLYfX62VaUYD2vvcLyXE/w== +"@firebase/remote-config-compat@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@firebase/remote-config-compat/-/remote-config-compat-0.1.1.tgz#8ff028e53b1f0b6c482257a5da371c7dea9928d3" + integrity sha512-ZHRHYTdDztXHxgYXzuuD6Goa6ScmAqtctXl2eC6D8vxA8fIGRQKHN+9AMwxm8b3JHzdVY/5XhAOmKCcFvPOgtw== dependencies: - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/remote-config" "0.2.0" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/remote-config" "0.3.0" "@firebase/remote-config-types" "0.2.0" - "@firebase/util" "1.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/remote-config-types@0.2.0": @@ -1629,26 +1618,26 @@ resolved "https://registry.yarnpkg.com/@firebase/remote-config-types/-/remote-config-types-0.2.0.tgz#1e2759fc01f20b58c564db42196f075844c3d1fd" integrity sha512-hqK5sCPeZvcHQ1D6VjJZdW6EexLTXNMJfPdTwbD8NrXUw6UjWC4KWhLK/TSlL0QPsQtcKRkaaoP+9QCgKfMFPw== -"@firebase/remote-config@0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@firebase/remote-config/-/remote-config-0.2.0.tgz#aa2bd7b34e0e40a259c3f0409a5084864f234f0f" - integrity sha512-hNZ+BqsTmfe8ogpeow95NSwQmKIeetKdPxKpyC6RZBeFUae782+2HrUx4/Quep6OZjOHQF6xZ5d3VOxu2ZKEfg== +"@firebase/remote-config@0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@firebase/remote-config/-/remote-config-0.3.0.tgz#43faf34eeb7407f7660eeca2790ccab25f76903d" + integrity sha512-Yf9/iXToC6Kbec1yOQ9mdTc1MP0mR2VCCR/n3Q+Ol3U+PML+ePXfqWiL2VHrUA86BeB2hpXF1BcTxvD4uOiDnA== dependencies: - "@firebase/component" "0.5.6" - "@firebase/installations" "0.5.0" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" + "@firebase/component" "0.5.7" + "@firebase/installations" "0.5.1" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" -"@firebase/storage-compat@0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@firebase/storage-compat/-/storage-compat-0.1.2.tgz#98e6b3516a70799935618c32e6b8937370587929" - integrity sha512-eff0e2qcDX188mqr7aKrqr4TIS25/cE6E7Xo9WRLe3c17nqGgmrYM4DDS3VDttNbf1j5XaoEnZVZafE9/BR3Rg== +"@firebase/storage-compat@0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@firebase/storage-compat/-/storage-compat-0.1.3.tgz#74a579aac6dc6e2c8293c8bdebb93bbcff0e0da9" + integrity sha512-m2htGJjCFlTONsqYRKXTfzkux3nbhpIpd72RK2iPkRPE69nQ0wiVplIE7bCaq3CSFMbkI3ETOtTTfW1wrOpF2g== dependencies: - "@firebase/component" "0.5.6" - "@firebase/storage" "0.8.2" + "@firebase/component" "0.5.7" + "@firebase/storage" "0.8.3" "@firebase/storage-types" "0.6.0" - "@firebase/util" "1.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/storage-types@0.6.0": @@ -1656,14 +1645,14 @@ resolved "https://registry.yarnpkg.com/@firebase/storage-types/-/storage-types-0.6.0.tgz#0b1af64a2965af46fca138e5b70700e9b7e6312a" integrity sha512-1LpWhcCb1ftpkP/akhzjzeFxgVefs6eMD2QeKiJJUGH1qOiows2w5o0sKCUSQrvrRQS1lz3SFGvNR1Ck/gqxeA== -"@firebase/storage@0.8.2": - version "0.8.2" - resolved "https://registry.yarnpkg.com/@firebase/storage/-/storage-0.8.2.tgz#e08c05d070a468f0976a3d0cd32318655f0ae3b7" - integrity sha512-I9mVYhQ/DkWI1MKHhYvI4dnguXdXC50S5ryehOcR/JmSwyYjh1+T+IFQp0hHb1VWTixShzWoSGo1PhbrolFmIA== +"@firebase/storage@0.8.3": + version "0.8.3" + resolved "https://registry.yarnpkg.com/@firebase/storage/-/storage-0.8.3.tgz#49bdfb47a1b136eebf884e7343038d8f3437f08c" + integrity sha512-oraycQ787tEr6xu2Qc4nngLz1YEoEjZ+lrjThx0CJZB7VwdlkIJ24TkzJ9xoeWc+cpo34deg/If4w8AU5/WupQ== dependencies: - "@firebase/component" "0.5.6" - "@firebase/util" "1.3.0" - node-fetch "2.6.1" + "@firebase/component" "0.5.7" + "@firebase/util" "1.4.0" + node-fetch "2.6.2" tslib "^2.1.0" "@firebase/util@1.2.0": @@ -1673,17 +1662,17 @@ dependencies: tslib "^2.1.0" -"@firebase/util@1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@firebase/util/-/util-1.3.0.tgz#e71113bdd5073e9736ceca665b54d9f6df232b20" - integrity sha512-SESvmYwuKOVCZ1ZxLbberbx+9cnbxpCa4CG2FUSQYqN6Ab8KyltegMDIsqMw5KyIBZ4n1phfHoOa22xo5NzAlQ== +"@firebase/util@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@firebase/util/-/util-1.4.0.tgz#81e985adba44b4d1f21ec9f5af9628d505891de8" + integrity sha512-Qn58d+DVi1nGn0bA9RV89zkz0zcbt6aUcRdyiuub/SuEvjKYstWmHcHwh1C0qmE1wPf9a3a+AuaRtduaGaRT7A== dependencies: tslib "^2.1.0" -"@firebase/webchannel-wrapper@0.5.1": - version "0.5.1" - resolved "https://registry.yarnpkg.com/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.5.1.tgz#a64d1af3c62e3bb89576ec58af880980a562bf4e" - integrity sha512-dZMzN0uAjwJXWYYAcnxIwXqRTZw3o14hGe7O6uhwjD1ZQWPVYA5lASgnNskEBra0knVBsOXB4KXg+HnlKewN/A== +"@firebase/webchannel-wrapper@0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.6.0.tgz#e18ea901c84917f8dadd0185048a9d00573fe595" + integrity sha512-Pz4+7HPzKvOFI1ICQ6pyUv/VgStEWq9IGiVaaV1cQLi66NIA1mD5INnY4CDNoVAxlkuZvDEUZ+cVHLQ8iwA2hQ== "@gar/promisify@^1.0.1": version "1.1.2" @@ -1765,7 +1754,18 @@ dependencies: "@types/node" ">=12.12.47" -"@grpc/proto-loader@^0.6.0", "@grpc/proto-loader@^0.6.1": +"@grpc/proto-loader@^0.6.0": + version "0.6.5" + resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.6.5.tgz#f23c7cb3e7076a8702f40c2b6678f06fb9950a55" + integrity sha512-GZdzyVQI1Bln/kCzIYgTKu+rQJ5dno0gVrfmLe4jqQu7T2e7svSwJzpCBqVU5hhBSJP3peuPjOMWsj5GR61YmQ== + dependencies: + "@types/long" "^4.0.1" + lodash.camelcase "^4.3.0" + long "^4.0.0" + protobufjs "^6.10.0" + yargs "^16.1.1" + +"@grpc/proto-loader@^0.6.1": version "0.6.4" resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.6.4.tgz#5438c0d771e92274e77e631babdc14456441cbdc" integrity sha512-7xvDvW/vJEcmLUltCUGOgWRPM8Oofv0eCFSVMuKqaqWJaXSzmB+m9hiyqe34QofAl4WAzIKUZZlinIF9FOHyTQ== @@ -2184,11 +2184,16 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== -"@types/node@*", "@types/node@>=10.0.0", "@types/node@>=12.12.47", "@types/node@>=13.7.0": +"@types/node@*", "@types/node@>=10.0.0": version "16.9.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.9.1.tgz#0611b37db4246c937feef529ddcc018cf8e35708" integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g== +"@types/node@>=12.12.47", "@types/node@>=13.7.0": + version "16.10.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.10.3.tgz#7a8f2838603ea314d1d22bb3171d899e15c57bd5" + integrity sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ== + "@types/node@^12.11.1": version "12.20.24" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.24.tgz#c37ac69cb2948afb4cef95f424fa0037971a9a5c" @@ -2585,10 +2590,10 @@ ansi-regex@^4.1.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-styles@^2.2.1: version "2.2.1" @@ -4735,7 +4740,7 @@ faye-websocket@0.11.3: dependencies: websocket-driver ">=0.5.1" -faye-websocket@^0.11.3: +faye-websocket@0.11.4, faye-websocket@^0.11.3: version "0.11.4" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== @@ -4884,36 +4889,36 @@ firebase-functions@^3.6.0: lodash "^4.17.14" firebase@^9.0.0: - version "9.0.2" - resolved "https://registry.yarnpkg.com/firebase/-/firebase-9.0.2.tgz#092019326f1c9a67ec00ec78d50f80244581c705" - integrity sha512-+wdsD3Sk3fOgplzv4yzBmJ3Pdr01QiFF38Zq+8hzd+Dv6ZKMrgiq5CRljCaWenhZ/j8nuvHlq82u64ZARaXC+w== - dependencies: - "@firebase/analytics" "0.7.0" - "@firebase/analytics-compat" "0.1.1" - "@firebase/app" "0.7.0" - "@firebase/app-check" "0.4.0" - "@firebase/app-check-compat" "0.1.1" - "@firebase/app-compat" "0.1.1" + version "9.1.1" + resolved "https://registry.yarnpkg.com/firebase/-/firebase-9.1.1.tgz#a2980cf397cdbf9933430576c0413ec5c30e2f62" + integrity sha512-106PqKLwWo4vINQUwEbk2aU/nAFhRbCBE2IdnQmf7UDaW4wqJGZcgRvy3jSyuZr/dkqnT7ymKX0GGrDSzNLU6g== + dependencies: + "@firebase/analytics" "0.7.1" + "@firebase/analytics-compat" "0.1.2" + "@firebase/app" "0.7.2" + "@firebase/app-check" "0.4.1" + "@firebase/app-check-compat" "0.1.2" + "@firebase/app-compat" "0.1.3" "@firebase/app-types" "0.7.0" - "@firebase/auth" "0.17.2" - "@firebase/auth-compat" "0.1.2" - "@firebase/database" "0.12.0" - "@firebase/database-compat" "0.1.0" - "@firebase/firestore" "3.0.2" - "@firebase/firestore-compat" "0.1.2" - "@firebase/functions" "0.7.1" - "@firebase/functions-compat" "0.1.2" - "@firebase/installations" "0.5.0" - "@firebase/messaging" "0.9.0" - "@firebase/messaging-compat" "0.1.0" - "@firebase/performance" "0.5.0" - "@firebase/performance-compat" "0.1.0" + "@firebase/auth" "0.18.1" + "@firebase/auth-compat" "0.1.4" + "@firebase/database" "0.12.1" + "@firebase/database-compat" "0.1.1" + "@firebase/firestore" "3.1.0" + "@firebase/firestore-compat" "0.1.3" + "@firebase/functions" "0.7.2" + "@firebase/functions-compat" "0.1.3" + "@firebase/installations" "0.5.1" + "@firebase/messaging" "0.9.1" + "@firebase/messaging-compat" "0.1.1" + "@firebase/performance" "0.5.1" + "@firebase/performance-compat" "0.1.1" "@firebase/polyfill" "0.3.36" - "@firebase/remote-config" "0.2.0" - "@firebase/remote-config-compat" "0.1.0" - "@firebase/storage" "0.8.2" - "@firebase/storage-compat" "0.1.2" - "@firebase/util" "1.3.0" + "@firebase/remote-config" "0.3.0" + "@firebase/remote-config-compat" "0.1.1" + "@firebase/storage" "0.8.3" + "@firebase/storage-compat" "0.1.3" + "@firebase/util" "1.4.0" flatted@^2.0.1: version "2.0.2" @@ -5159,7 +5164,7 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@7.1.7, glob@^7.0.3, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.1.7: +glob@7.1.7, glob@^7.0.3, glob@^7.1.1, glob@^7.1.4, glob@^7.1.6, glob@^7.1.7: version "7.1.7" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== @@ -5171,6 +5176,18 @@ glob@7.1.7, glob@^7.0.3, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glo once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.1.3: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -6351,7 +6368,7 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -jszip@^3.5.0, jszip@^3.6.0: +jszip@^3.6.0: version "3.7.1" resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.7.1.tgz#bd63401221c15625a1228c556ca8a68da6fda3d9" integrity sha512-ghL0tz1XG9ZEmRMcEN2vt7xabrDdqHHeykgARpmZ0BiIctWxM47Vt63ZO2dnp4QYt/xJVLLy5Zv1l/xRdh2byg== @@ -7202,11 +7219,18 @@ node-fetch@2.6.1: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== -node-fetch@^2.6.1: +node-fetch@2.6.2, node-fetch@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.2.tgz#986996818b73785e47b1965cc34eb093a1d464d0" integrity sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA== +node-fetch@2.6.5: + version "2.6.5" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.5.tgz#42735537d7f080a7e5f78b6c549b7146be1742fd" + integrity sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ== + dependencies: + whatwg-url "^5.0.0" + node-forge@^0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" @@ -8865,7 +8889,7 @@ rfdc@^1.1.4: resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== -rimraf@^2.6.3, rimraf@^2.7.1: +rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -9027,20 +9051,20 @@ select-hose@^2.0.0: resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= -selenium-webdriver@4.0.0-beta.1: - version "4.0.0-beta.1" - resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.0.0-beta.1.tgz#db645b0d775f26e4e12235db05796a1bc1e7efda" - integrity sha512-DJ10z6Yk+ZBaLrt1CLElytQ/FOayx29ANKDtmtyW1A6kCJx3+dsc5fFMOZxwzukDniyYsC3OObT5pUAsgkjpxQ== +selenium-webdriver@4.0.0-rc-1: + version "4.0.0-rc-1" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.0.0-rc-1.tgz#b1e7e5821298c8a071e988518dd6b759f0c41281" + integrity sha512-bcrwFPRax8fifRP60p7xkWDGSJJoMkPAzufMlk5K2NyLPht/YZzR2WcIk1+3gR8VOCLlst1P2PI+MXACaFzpIw== dependencies: - jszip "^3.5.0" - rimraf "^2.7.1" + jszip "^3.6.0" + rimraf "^3.0.2" tmp "^0.2.1" - ws "^7.3.1" + ws ">=7.4.6" selenium-webdriver@^4.0.0-beta.2: - version "4.0.0-rc-1" - resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.0.0-rc-1.tgz#b1e7e5821298c8a071e988518dd6b759f0c41281" - integrity sha512-bcrwFPRax8fifRP60p7xkWDGSJJoMkPAzufMlk5K2NyLPht/YZzR2WcIk1+3gR8VOCLlst1P2PI+MXACaFzpIw== + version "4.0.0-rc-2" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.0.0-rc-2.tgz#f533487d2612806b12473a58d86db15293c7b791" + integrity sha512-HT974l00r7wdZL+SPS0f8lBLVYe/aKGAFONMvVroL7z9mHm3PC30IirsYqrvSkw51Pom3XJiN5gjXBRkxuHAdw== dependencies: jszip "^3.6.0" rimraf "^3.0.2" @@ -9623,13 +9647,13 @@ string-width@^3.0.0, string-width@^3.1.0: strip-ansi "^5.1.0" string-width@^4.1.0, string-width@^4.2.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" - integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" + strip-ansi "^6.0.1" string_decoder@^1.1.1: version "1.3.0" @@ -9666,12 +9690,12 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: - ansi-regex "^5.0.0" + ansi-regex "^5.0.1" strip-eof@^1.0.0: version "1.0.0" @@ -9973,6 +9997,11 @@ tr46@^2.1.0: dependencies: punycode "^2.1.1" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + tree-kill@1.2.2, tree-kill@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" @@ -10307,6 +10336,11 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + webidl-conversions@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" @@ -10491,6 +10525,14 @@ whatwg-mimetype@^2.3.0: resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + whatwg-url@^8.0.0, whatwg-url@^8.5.0: version "8.7.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" @@ -10602,9 +10644,9 @@ write-file-atomic@^3.0.0: typedarray-to-buffer "^3.1.5" ws@>=7.4.6: - version "8.2.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.2.tgz#ca684330c6dd6076a737250ed81ac1606cb0a63e" - integrity sha512-Q6B6H2oc8QY3llc3cB8kVmQ6pnJWVQbP7Q5algTcIxx7YEpc0oU4NBVHlztA7Ekzfhw2r0rPducMUiCGWKQRzw== + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== ws@^6.2.1: version "6.2.2" diff --git a/src/compat/remote-config/remote-config.ts b/src/compat/remote-config/remote-config.ts index df5c99e88..d62fb70d5 100644 --- a/src/compat/remote-config/remote-config.ts +++ b/src/compat/remote-config/remote-config.ts @@ -18,10 +18,10 @@ import { ɵAngularFireSchedulers, keepUnstableUntilFirst } from '@angular/fire'; import { ɵlazySDKProxy, ɵPromiseProxy, ɵapplyMixins } from '@angular/fire/compat'; import { FirebaseOptions } from 'firebase/app'; import { ɵfirebaseAppFactory, FIREBASE_APP_NAME, FIREBASE_OPTIONS, ɵcacheInstance } from '@angular/fire/compat'; -import { isPlatformBrowser } from '@angular/common'; import firebase from 'firebase/compat/app'; import { Settings } from './interfaces'; import { proxyPolyfillCompat } from './base'; +import { isSupported } from 'firebase/remote-config'; export interface ConfigTemplate { [key: string]: string | number | boolean; @@ -134,8 +134,8 @@ export class AngularFireRemoteConfig { ) { const remoteConfig$ = of(undefined).pipe( observeOn(schedulers.outsideAngular), - switchMap(() => isPlatformBrowser(platformId) ? import('firebase/compat/remote-config') : EMPTY), - switchMap(() => import('@firebase/remote-config')), + switchMap(() => isSupported()), + switchMap(isSupported => isSupported ? import('firebase/compat/remote-config') : EMPTY), map(() => ɵfirebaseAppFactory(options, zone, name)), map(app => ɵcacheInstance(`${app.name}.remote-config`, 'AngularFireRemoteConfig', app.name, () => { const rc = app.remoteConfig(); diff --git a/src/remote-config/firebase.ts b/src/remote-config/firebase.ts index 0731a966f..dd0ba60d6 100644 --- a/src/remote-config/firebase.ts +++ b/src/remote-config/firebase.ts @@ -12,6 +12,7 @@ import { getRemoteConfig as _getRemoteConfig, getString as _getString, getValue as _getValue, + isSupported as _isSupported, setLogLevel as _setLogLevel } from 'firebase/remote-config'; @@ -25,4 +26,5 @@ export const getNumber = ɵzoneWrap(_getNumber, true); export const getRemoteConfig = ɵzoneWrap(_getRemoteConfig, true); export const getString = ɵzoneWrap(_getString, true); export const getValue = ɵzoneWrap(_getValue, true); +export const isSupported = ɵzoneWrap(_isSupported, true); export const setLogLevel = ɵzoneWrap(_setLogLevel, true); diff --git a/src/remote-config/remote-config.module.ts b/src/remote-config/remote-config.module.ts index d9319bc05..f9faeb2c9 100644 --- a/src/remote-config/remote-config.module.ts +++ b/src/remote-config/remote-config.module.ts @@ -1,28 +1,28 @@ -import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders, PLATFORM_ID, Injector } from '@angular/core'; -import { RemoteConfig as FirebaseRemoteConfig } from 'firebase/remote-config'; +import { NgModule, Optional, NgZone, InjectionToken, ModuleWithProviders, Injector, APP_INITIALIZER } from '@angular/core'; +import { RemoteConfig as FirebaseRemoteConfig, isSupported } from 'firebase/remote-config'; import { ɵgetDefaultInstanceOf, ɵAngularFireSchedulers, VERSION } from '@angular/fire'; import { RemoteConfig, RemoteConfigInstances, REMOTE_CONFIG_PROVIDER_NAME } from './remote-config'; import { FirebaseApps, FirebaseApp } from '@angular/fire/app'; import { registerVersion } from 'firebase/app'; -import { isPlatformBrowser } from '@angular/common'; export const PROVIDED_REMOTE_CONFIG_INSTANCES = new InjectionToken('angularfire2.remote-config-instances'); +const IS_SUPPORTED = new InjectionToken('angularfire2.remote-config.isSupported'); + +const isSupportedSymbol = Symbol('angularfire2.remote-config.isSupported'); export function defaultRemoteConfigInstanceFactory( + isSupported: boolean, provided: FirebaseRemoteConfig[]|undefined, defaultApp: FirebaseApp, - // tslint:disable-next-line:ban-types - platform: Object ) { - if (!isPlatformBrowser(platform)) { return null; } + if (!isSupported) { return null; } const defaultRemoteConfig = ɵgetDefaultInstanceOf(REMOTE_CONFIG_PROVIDER_NAME, provided, defaultApp); return defaultRemoteConfig && new RemoteConfig(defaultRemoteConfig); } export function remoteConfigInstanceFactory(fn: (injector: Injector) => FirebaseRemoteConfig) { - // tslint:disable-next-line:ban-types - return (zone: NgZone, platform: Object, injector: Injector) => { - if (!isPlatformBrowser(platform)) { return null; } + return (zone: NgZone, isSupported: boolean, injector: Injector) => { + if (!isSupported) { return null; } const remoteConfig = zone.runOutsideAngular(() => fn(injector)); return new RemoteConfig(remoteConfig); }; @@ -39,9 +39,9 @@ const DEFAULT_REMOTE_CONFIG_INSTANCE_PROVIDER = { provide: RemoteConfig, useFactory: defaultRemoteConfigInstanceFactory, deps: [ + IS_SUPPORTED, [new Optional(), PROVIDED_REMOTE_CONFIG_INSTANCES ], FirebaseApp, - PLATFORM_ID, ] }; @@ -49,6 +49,11 @@ const DEFAULT_REMOTE_CONFIG_INSTANCE_PROVIDER = { providers: [ DEFAULT_REMOTE_CONFIG_INSTANCE_PROVIDER, REMOTE_CONFIG_INSTANCES_PROVIDER, + { + provide: APP_INITIALIZER, + useValue: () => isSupported().then(it => globalThis[isSupportedSymbol] = it), + multi: true, + }, ] }) export class RemoteConfigModule { @@ -61,12 +66,15 @@ export function provideRemoteConfig(fn: () => FirebaseRemoteConfig, ...deps: any return { ngModule: RemoteConfigModule, providers: [{ + provide: IS_SUPPORTED, + useFactory: () => globalThis[isSupportedSymbol], + }, { provide: PROVIDED_REMOTE_CONFIG_INSTANCES, useFactory: remoteConfigInstanceFactory(fn), multi: true, deps: [ NgZone, - PLATFORM_ID, + IS_SUPPORTED, Injector, ɵAngularFireSchedulers, FirebaseApps, diff --git a/tools/build.ts b/tools/build.ts index 9132bb6f1..77f39f2a3 100644 --- a/tools/build.ts +++ b/tools/build.ts @@ -65,6 +65,9 @@ ${zoneWrapped.map(([importName, exportName]) => `export const ${exportName} = ɵ reexport('auth', 'firebase', 'firebase/auth', tsKeys(), { debugErrorMap: null, inMemoryPersistence: null, + browserLocalPersistence: null, + browserSessionPersistence: null, + indexedDBLocalPersistence: null, prodErrorMap: null, }), reexport('database', 'rxfire', 'rxfire/database', tsKeys()), diff --git a/yarn.lock b/yarn.lock index 0188c638e..c557393c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1425,15 +1425,15 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz#90420f9f9c6d3987f176a19a7d8e764271a2f55d" integrity sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g== -"@firebase/analytics-compat@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@firebase/analytics-compat/-/analytics-compat-0.1.1.tgz#77a3e5d28f15df303c3836db4740a43955fcfcac" - integrity sha512-pMTrA8cxMXFRv7bwZEXXz0NCepnyH2Jay/32RZ7xAufij2VJhF5S1BtfCO0wuri3FB94rlM8SmSEbwxxHcAtVg== +"@firebase/analytics-compat@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@firebase/analytics-compat/-/analytics-compat-0.1.2.tgz#db115aabf1b30b43567e45cca86f3856aafb93b4" + integrity sha512-TpWpz0s8EgVt9aqyOCFktONqVkjyrNRR4esn3cEYrueH+XXSMDLWY9oFHuUJzntcoEOlOBWMvpsJCPG/1kthkg== dependencies: - "@firebase/analytics" "0.7.0" + "@firebase/analytics" "0.7.1" "@firebase/analytics-types" "0.7.0" - "@firebase/component" "0.5.6" - "@firebase/util" "1.3.0" + "@firebase/component" "0.5.7" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/analytics-types@0.7.0": @@ -1441,26 +1441,26 @@ resolved "https://registry.yarnpkg.com/@firebase/analytics-types/-/analytics-types-0.7.0.tgz#91960e7c87ce8bf18cf8dd9e55ccbf5dc3989b5d" integrity sha512-DNE2Waiwy5+zZnCfintkDtBfaW6MjIG883474v6Z0K1XZIvl76cLND4iv0YUb48leyF+PJK1KO2XrgHb/KpmhQ== -"@firebase/analytics@0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@firebase/analytics/-/analytics-0.7.0.tgz#7f4450936a2cac3227cc6439130c09b9a0a7d83e" - integrity sha512-YEPyeW6CV8xbIvWaJMvfRdWUPKe/xchJ1bjV6GpLfkYRX+ZE1/YSNU14pX292M4bZ6Qg+bbu2DuWp8fEpa/YQg== +"@firebase/analytics@0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@firebase/analytics/-/analytics-0.7.1.tgz#e95cf81ffc748fc73422eed081d4dd8e1e5f1e0c" + integrity sha512-fTUN47UK4obzIJwmgLMJU46dWZ7pzitCEO+80pQZC7mdLlVs/NW0+tMf6rETwMpKjGSgb25cKidpgEuioQtT7w== dependencies: - "@firebase/component" "0.5.6" - "@firebase/installations" "0.5.0" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" + "@firebase/component" "0.5.7" + "@firebase/installations" "0.5.1" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" -"@firebase/app-check-compat@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@firebase/app-check-compat/-/app-check-compat-0.1.1.tgz#84c7ef29bb683fd3dea66a66f82b799474c904ee" - integrity sha512-XTV5Ns0Lpwn5GgXV5T0soOkoOGACaw9xiNvAXcISQYFBIse0k7fKo8V5J9VUS1ppzGpyTRCg0m9efz4CNrwPyQ== +"@firebase/app-check-compat@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@firebase/app-check-compat/-/app-check-compat-0.1.2.tgz#1e5480a9f83c1cec814b3a11032a797b1a50eaec" + integrity sha512-JB+OHk4Cp9ZgT+UfX0A+lwH1AoM5Y2X1rDhmhCsEXcKKwz1w9DpL9PjStciP8UYg1dpqbp5p9OMxmty+21EBsA== dependencies: - "@firebase/app-check" "0.4.0" - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" + "@firebase/app-check" "0.4.1" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/app-check-interop-types@0.1.0": @@ -1468,25 +1468,25 @@ resolved "https://registry.yarnpkg.com/@firebase/app-check-interop-types/-/app-check-interop-types-0.1.0.tgz#83afd9d41f99166c2bdb2d824e5032e9edd8fe53" integrity sha512-uZfn9s4uuRsaX5Lwx+gFP3B6YsyOKUE+Rqa6z9ojT4VSRAsZFko9FRn6OxQUA1z5t5d08fY4pf+/+Dkd5wbdbA== -"@firebase/app-check@0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@firebase/app-check/-/app-check-0.4.0.tgz#a048fc396b2a97ef8eba77fe909efbff07a5c75c" - integrity sha512-KQ/k8cukzZbH/LC9Iu5/Dbhr7w6byu8bYjfCA38B6v8aISgASYfP/nirxRD+hSuDoxXtAnPGEuv+v0YU3D1R2w== +"@firebase/app-check@0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@firebase/app-check/-/app-check-0.4.1.tgz#60e329b3871574a0431536edca69e0d0a8cbd674" + integrity sha512-Kpqh0Y2zpx+acTL7eOVYIWBOmAwoconJpqOAlByGNXuxm/ccP00XREo+HsqaC7wapZRXh+h8BK0jZjvdV36qow== dependencies: - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" -"@firebase/app-compat@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.1.1.tgz#47d5f5ac350f59ea4b721f17e01b1e46a1a3154a" - integrity sha512-AoUO7PnQlDPyMAvAE972kBhrwXRZRLGdHM8obyIeTzPNqIiEoULD4Rdq5TBB4UmV2HYAlYdrS+dk4nuWx67w6A== +"@firebase/app-compat@0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.1.3.tgz#4757c8f65d2a067d24afdfef4f736a5f53c66656" + integrity sha512-+/U2RgRLfLznPuluIMW3bsAehTBTVWKxA6l6jjk9noozPuP99xOulReMqf5kCrXVdW1aMHdRuKfntjbTAR8+aw== dependencies: - "@firebase/app" "0.7.0" - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" + "@firebase/app" "0.7.2" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/app-types@0.6.3": @@ -1499,26 +1499,26 @@ resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.7.0.tgz#c9e16d1b8bed1a991840b8d2a725fb58d0b5899f" integrity sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg== -"@firebase/app@0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.7.0.tgz#989e9f354951de2a8ac806f6e3fa0afd9f80b470" - integrity sha512-l4Pd69re6JyjumQrl719dnY5JSKROSYda/0N2wzOhSzqg8DsZOIErr8+xj6QAE6BtNsoIEk7ma9WMS/2r02MhA== +"@firebase/app@0.7.2": + version "0.7.2" + resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.7.2.tgz#0df26d6e9861d5ebe038d4e1f10b63111a28a1f7" + integrity sha512-xKO3KWxVqCLijJToaBGvBnXCaVGvIw+rT2Dtd9B2iyOFJieQQ+xx8/zRWgoSqbMBIZ2crQVr0KdsoyP9D2nQfg== dependencies: - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" -"@firebase/auth-compat@0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@firebase/auth-compat/-/auth-compat-0.1.2.tgz#a971cb7859eb4d45c233043bea102993376d9fca" - integrity sha512-0eqWSV4XoyOltT4HVJUzh8hBFNO5f78ZGDplRQImQ97/6wR45x6Q/9R19KTWOd109+3Axw6Orfq2cSNY0opgEA== +"@firebase/auth-compat@0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@firebase/auth-compat/-/auth-compat-0.1.4.tgz#d55084f0d37086d58a1da4748c9bbec2ede0a80a" + integrity sha512-Vn7Dsxa7B50ihgDAMQAVb/IxU9tcQyR1JDbWjZzf2b1212hBuuwEs1V1u01xoKunMXMSg+P8ztbG7IRxOj2FdQ== dependencies: - "@firebase/auth" "0.17.2" + "@firebase/auth" "0.18.1" "@firebase/auth-types" "0.11.0" - "@firebase/component" "0.5.6" - "@firebase/util" "1.3.0" - node-fetch "2.6.1" + "@firebase/component" "0.5.7" + "@firebase/util" "1.4.0" + node-fetch "2.6.5" selenium-webdriver "^4.0.0-beta.2" tslib "^2.1.0" @@ -1532,16 +1532,16 @@ resolved "https://registry.yarnpkg.com/@firebase/auth-types/-/auth-types-0.11.0.tgz#b9c73c60ca07945b3bbd7a097633e5f78fa9e886" integrity sha512-q7Bt6cx+ySj9elQHTsKulwk3+qDezhzRBFC9zlQ1BjgMueUOnGMcvqmU0zuKlQ4RhLSH7MNAdBV2znVaoN3Vxw== -"@firebase/auth@0.17.2": - version "0.17.2" - resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-0.17.2.tgz#54ad76cfdc2f6d1201fb780365cf7d362586f3c6" - integrity sha512-t1iHB5Eg7vAbyOEzMMarsyJNGiO2xP8Zag0hLRVXWVaWymXZnyVKp62sXqyonvz4eVT8+iGBjDySB9zKIb5Pqg== +"@firebase/auth@0.18.1": + version "0.18.1" + resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-0.18.1.tgz#2cba86c5ac614aea8ea1bdc55e479530c187b5ce" + integrity sha512-q455ls7Hjug3yGp7htLL/LABqySoXGXL/ADLJPyiSnVl22a5oQWuTKUL6N5PAXHc5LwygFfHYiHrNhpQDaGm3w== dependencies: - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" - node-fetch "2.6.1" - selenium-webdriver "4.0.0-beta.1" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" + node-fetch "2.6.5" + selenium-webdriver "4.0.0-rc-1" tslib "^2.1.0" "@firebase/component@0.5.5": @@ -1552,24 +1552,24 @@ "@firebase/util" "1.2.0" tslib "^2.1.0" -"@firebase/component@0.5.6": - version "0.5.6" - resolved "https://registry.yarnpkg.com/@firebase/component/-/component-0.5.6.tgz#6b7c7aff69866e0925721543a2ef5f47b0f97cbe" - integrity sha512-GyQJ+2lrhsDqeGgd1VdS7W+Y6gNYyI0B51ovNTxeZVG/W8I7t9MwEiCWsCvfm5wQgfsKp9dkzOcJrL5k8oVO/Q== +"@firebase/component@0.5.7": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@firebase/component/-/component-0.5.7.tgz#a50c5fbd14a2136a99ade6f59f53498729c0f174" + integrity sha512-CiAHUPXh2hn/lpzMShNmfAxHNQhKQwmQUJSYMPCjf2bCCt4Z2vLGpS+UWEuNFm9Zf8LNmkS+Z+U/s4Obi5carg== dependencies: - "@firebase/util" "1.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" -"@firebase/database-compat@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@firebase/database-compat/-/database-compat-0.1.0.tgz#f02abaa9f493fd14aaae6e2b34262bafc5d033c7" - integrity sha512-jLN0JMYnYijg8f3QFtSuPGNuKAt3yYVRsHHlR8sADgx8MptByRRwVmMOk7QPc/DY7qscZIJow3hXFwvbeApFLA== - dependencies: - "@firebase/component" "0.5.6" - "@firebase/database" "0.12.0" - "@firebase/database-types" "0.9.0" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" +"@firebase/database-compat@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@firebase/database-compat/-/database-compat-0.1.1.tgz#9fe69e3bd3f71d29011bb6ca793f38edb65ca536" + integrity sha512-K3DFWiw0YkLZtlfA9TOGPw6zVXKu5dQ1XqIGztUufFVRYW8IizReXVxzSSmJNR4Adr2LiU9j66Wenc6e5UfwaQ== + dependencies: + "@firebase/component" "0.5.7" + "@firebase/database" "0.12.1" + "@firebase/database-types" "0.9.1" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/database-types@0.7.3", "@firebase/database-types@^0.7.2": @@ -1579,24 +1579,24 @@ dependencies: "@firebase/app-types" "0.6.3" -"@firebase/database-types@0.9.0": - version "0.9.0" - resolved "https://registry.yarnpkg.com/@firebase/database-types/-/database-types-0.9.0.tgz#dad3db745531f40b60f7726a76b2bf6bbf6c6471" - integrity sha512-x2TeTVnMZGPvT3y4Nayio4WprQA/zGwqMrPMQwSdF+PFnaFJAhA/eLgUB6cmWFzFYO9VvmuRkFzDzo6ezTo1Zw== +"@firebase/database-types@0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@firebase/database-types/-/database-types-0.9.1.tgz#0cab989e8154d812b535d80f23c1578b1d391f5f" + integrity sha512-RUixK/YrbpxbfdE+nYP0wMcEsz1xPTnafP0q3UlSS/+fW744OITKtR1J0cMRaXbvY7EH0wUVTNVkrtgxYY8IgQ== dependencies: "@firebase/app-types" "0.7.0" - "@firebase/util" "1.3.0" + "@firebase/util" "1.4.0" -"@firebase/database@0.12.0": - version "0.12.0" - resolved "https://registry.yarnpkg.com/@firebase/database/-/database-0.12.0.tgz#2aa33138128cfcaf74388efe13e0eda10825d564" - integrity sha512-/gl6z6fAxAAFAdDllzidzweGpuXJu0b9AusSLrdW4LpP6KCuxJbhonMJuSGpHLzAHzx6Q9uitbvqHqBb17sttQ== +"@firebase/database@0.12.1": + version "0.12.1" + resolved "https://registry.yarnpkg.com/@firebase/database/-/database-0.12.1.tgz#7e43f27ac4057858d5bd0dd371b134b304fecdb0" + integrity sha512-Ethk0hc476qnkSKNBa+8Yc7iM8AO69HYWsaD+QUC983FZtnuMyNLHtEeSUbLQYvyHo7cOjcc52slop14WmfZeQ== dependencies: "@firebase/auth-interop-types" "0.1.6" - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" - faye-websocket "0.11.3" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" + faye-websocket "0.11.4" tslib "^2.1.0" "@firebase/database@^0.10.0": @@ -1612,15 +1612,15 @@ faye-websocket "0.11.3" tslib "^2.1.0" -"@firebase/firestore-compat@0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@firebase/firestore-compat/-/firestore-compat-0.1.2.tgz#af9e28735376ee04c147ea3ac11b592b3f7a68ac" - integrity sha512-xtjj2qOBN0+S5KlXmWa5UozGmYJ1OAGBNT0qkCSvzQitHED5/B2fNwKnpy7Em+Zu3Yc3r/eM94OGx93USFXifg== +"@firebase/firestore-compat@0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@firebase/firestore-compat/-/firestore-compat-0.1.3.tgz#a898f6819b9d87134b5e09fcf9b2fb5bfc0ee68b" + integrity sha512-tO3uAkIguKeFeKPu99GR7F7v1/Hc8nV1h7B1kdpkVRRBe+NfVYA3qAUictQ3OAA0oy7Ae9z4SfEURO/R1b6YlQ== dependencies: - "@firebase/component" "0.5.6" - "@firebase/firestore" "3.0.2" + "@firebase/component" "0.5.7" + "@firebase/firestore" "3.1.0" "@firebase/firestore-types" "2.5.0" - "@firebase/util" "1.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/firestore-types@2.5.0": @@ -1628,29 +1628,29 @@ resolved "https://registry.yarnpkg.com/@firebase/firestore-types/-/firestore-types-2.5.0.tgz#16fca40b6980fdb000de86042d7a96635f2bcdd7" integrity sha512-I6c2m1zUhZ5SH0cWPmINabDyH5w0PPFHk2UHsjBpKdZllzJZ2TwTkXbDtpHUZNmnc/zAa0WNMNMvcvbb/xJLKA== -"@firebase/firestore@3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@firebase/firestore/-/firestore-3.0.2.tgz#594130bb125803b6e28611075c2f396f59ba8186" - integrity sha512-AWh1pugDifwCXHaQalZHp+Hr/3o+cxYvlbgQrPB35bh1A3do4I1xim/8Pba7gtpTzlClDryd5pK/XbK0TC/2kg== +"@firebase/firestore@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@firebase/firestore/-/firestore-3.1.0.tgz#0a59e41f164b28116aca1a264acef0dbc8e5a585" + integrity sha512-vOXueHNRjlgBlKVCWuUDhr3dQW2hJwbcqcJaFiIV9V+PamfyhOHzX8pEQkrPort4YQQvoRmY9uiFhfOGj2hbeA== dependencies: - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" - "@firebase/webchannel-wrapper" "0.5.1" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" + "@firebase/webchannel-wrapper" "0.6.0" "@grpc/grpc-js" "^1.3.2" "@grpc/proto-loader" "^0.6.0" - node-fetch "2.6.1" + node-fetch "2.6.2" tslib "^2.1.0" -"@firebase/functions-compat@0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@firebase/functions-compat/-/functions-compat-0.1.2.tgz#557461ed4f2928747461c6b2d246ac328aea3248" - integrity sha512-eisJazUrqOL/pAZJPqamYiaAyV3ch6GQMx8Sso792tvRr8SFsNCFbN9eVun0U0ubWAON5qdLoruoc6npXg6FIg== +"@firebase/functions-compat@0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@firebase/functions-compat/-/functions-compat-0.1.3.tgz#19758884bf41752102bd0a420be2aa49ee2d45de" + integrity sha512-NdobePNq5LUHCI1dJHUGlOTw+Qmq/FJre981/ELEMBdEs95kmKwnXB2UaLjAQYWkgkr4YS3lEnNpsiSTaEHFCg== dependencies: - "@firebase/component" "0.5.6" - "@firebase/functions" "0.7.1" + "@firebase/component" "0.5.7" + "@firebase/functions" "0.7.2" "@firebase/functions-types" "0.5.0" - "@firebase/util" "1.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/functions-types@0.5.0": @@ -1658,26 +1658,26 @@ resolved "https://registry.yarnpkg.com/@firebase/functions-types/-/functions-types-0.5.0.tgz#b50ba95ccce9e96f7cda453228ffe1684645625b" integrity sha512-qza0M5EwX+Ocrl1cYI14zoipUX4gI/Shwqv0C1nB864INAD42Dgv4v94BCyxGHBg2kzlWy8PNafdP7zPO8aJQA== -"@firebase/functions@0.7.1": - version "0.7.1" - resolved "https://registry.yarnpkg.com/@firebase/functions/-/functions-0.7.1.tgz#aa95aaed34649d0656d50df0ed21802f117cca88" - integrity sha512-F6XZVVBpqupCX7/YXpdzyXKYCeLVmHO/jxAKbN9I4B+c8doDqVtGkO23DPzf4ppzR4FuXDiKEEU9ZZ85kqZ1QA== +"@firebase/functions@0.7.2": + version "0.7.2" + resolved "https://registry.yarnpkg.com/@firebase/functions/-/functions-0.7.2.tgz#9628afb88c0c9d302969b4dd37f09010b18c43f4" + integrity sha512-B+b57xXtpsRYD3UgVtteeyavXjXfBTtuv+sG8LA0vgJs6bhORswVlKZQqpfW9SDxCMBwzzytzn1m3ZZGfUw2Lg== dependencies: "@firebase/app-check-interop-types" "0.1.0" "@firebase/auth-interop-types" "0.1.6" - "@firebase/component" "0.5.6" + "@firebase/component" "0.5.7" "@firebase/messaging-interop-types" "0.1.0" - "@firebase/util" "1.3.0" - node-fetch "2.6.1" + "@firebase/util" "1.4.0" + node-fetch "2.6.2" tslib "^2.1.0" -"@firebase/installations@0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@firebase/installations/-/installations-0.5.0.tgz#4a21e1c7467795802b031af413df2555b17cf1b1" - integrity sha512-wF1CKIx+SoiEbtNdutulxW4z80B5lGXW+8JdAtcKQwgKxF0VtlCaDFsd9AEB3aTtzIve5UkGak8hQOMvvOpydg== +"@firebase/installations@0.5.1": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@firebase/installations/-/installations-0.5.1.tgz#3c515494fad8fba552ae0f01c675219e29e218e2" + integrity sha512-KZ1XHrEPmCx3Z70P9d8mHmYEZXA/uiLIkV0D8R45Q65c0DUxBDm5tSQs56QWofxB/wx16xmO3xAZw4BdJUBnlQ== dependencies: - "@firebase/component" "0.5.6" - "@firebase/util" "1.3.0" + "@firebase/component" "0.5.7" + "@firebase/util" "1.4.0" idb "3.0.2" tslib "^2.1.0" @@ -1686,14 +1686,21 @@ resolved "https://registry.yarnpkg.com/@firebase/logger/-/logger-0.2.6.tgz#3aa2ca4fe10327cabf7808bd3994e88db26d7989" integrity sha512-KIxcUvW/cRGWlzK9Vd2KB864HlUnCfdTH0taHE0sXW5Xl7+W68suaeau1oKNEqmc3l45azkd4NzXTCWZRZdXrw== -"@firebase/messaging-compat@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@firebase/messaging-compat/-/messaging-compat-0.1.0.tgz#ab164540f6ba954c8d150b2e96dc6bf8c1536eb4" - integrity sha512-58qQmKwOiXhxZwrRwwjQDbjlRx1uMVVuV/DNbDzqilDJDdoYXMdK6RBTF9Bs51qy/Z1BI2Q9B1JX01QYlgZpxQ== +"@firebase/logger@0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@firebase/logger/-/logger-0.3.0.tgz#a3992e40f62c10276dbfcb8b4ab376b7e25d7fd9" + integrity sha512-7oQ+TctqekfgZImWkKuda50JZfkmAKMgh5qY4aR4pwRyqZXuJXN1H/BKkHvN1y0S4XWtF0f/wiCLKHhyi1ppPA== dependencies: - "@firebase/component" "0.5.6" - "@firebase/messaging" "0.9.0" - "@firebase/util" "1.3.0" + tslib "^2.1.0" + +"@firebase/messaging-compat@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@firebase/messaging-compat/-/messaging-compat-0.1.1.tgz#aef5045cc30c781e33aa9030e26feca3f7aedda4" + integrity sha512-8FxrQjJCOfP9HibFsymT3qB18rBBmMPxOV+k0n6B7L6KW6Idswq01hMW12d93ZnvlNNKdikCKwUtBNbITBd8FA== + dependencies: + "@firebase/component" "0.5.7" + "@firebase/messaging" "0.9.1" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/messaging-interop-types@0.1.0": @@ -1701,28 +1708,28 @@ resolved "https://registry.yarnpkg.com/@firebase/messaging-interop-types/-/messaging-interop-types-0.1.0.tgz#bdac02dd31edd5cb9eec37b1db698ea5e2c1a631" integrity sha512-DbvUl/rXAZpQeKBnwz0NYY5OCqr2nFA0Bj28Fmr3NXGqR4PAkfTOHuQlVtLO1Nudo3q0HxAYLa68ZDAcuv2uKQ== -"@firebase/messaging@0.9.0": - version "0.9.0" - resolved "https://registry.yarnpkg.com/@firebase/messaging/-/messaging-0.9.0.tgz#a868bea75d0c26210903178cf22d31c47bc84584" - integrity sha512-NTUB+gVJsgL/f6wqwUlgadaNuLZvyk1IlTcRvR3391t8jDSWOT2efwzNqcI7Xv4nhzaiPhzAQ4ncH/m8kfUUXQ== +"@firebase/messaging@0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@firebase/messaging/-/messaging-0.9.1.tgz#4403dc5fdb2193818cecc359a4b31504c2cd5ac8" + integrity sha512-0g3JWTfkv0WHnu4xgx1zcChJXU2dLjWT0e2MI13Q7NbP3TgLu5CgQ/H/lad16j4Zb4RNqZbAUJurEAB6v2BJ/w== dependencies: - "@firebase/component" "0.5.6" - "@firebase/installations" "0.5.0" + "@firebase/component" "0.5.7" + "@firebase/installations" "0.5.1" "@firebase/messaging-interop-types" "0.1.0" - "@firebase/util" "1.3.0" + "@firebase/util" "1.4.0" idb "3.0.2" tslib "^2.1.0" -"@firebase/performance-compat@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@firebase/performance-compat/-/performance-compat-0.1.0.tgz#c1edeccd9b60d83de26d8e645e0d2ddd64e9a2d7" - integrity sha512-H+/A5+y/15hFn5FHRP8lcogDzO6qm9YoACNEXn71UN4PiGQ+/BbHkQafDEXxD6wLfqfqR8u8oclHPFIYxMBF7Q== +"@firebase/performance-compat@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@firebase/performance-compat/-/performance-compat-0.1.1.tgz#c895aaa57a08b3b9be035de764ccad4b02cb4e52" + integrity sha512-xN/TjU0hVNiJshZzrUvPYB+3sPS9SgaWrfxh3p0eGFVdwHp/3Z8HlT772bkHAEKXVc64v19ktpUVd+sF5aoJNQ== dependencies: - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/performance" "0.5.0" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/performance" "0.5.1" "@firebase/performance-types" "0.1.0" - "@firebase/util" "1.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/performance-types@0.1.0": @@ -1730,15 +1737,15 @@ resolved "https://registry.yarnpkg.com/@firebase/performance-types/-/performance-types-0.1.0.tgz#5e6efa9dc81860aee2cb7121b39ae8fa137e69fc" integrity sha512-6p1HxrH0mpx+622Ql6fcxFxfkYSBpE3LSuwM7iTtYU2nw91Hj6THC8Bc8z4nboIq7WvgsT/kOTYVVZzCSlXl8w== -"@firebase/performance@0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@firebase/performance/-/performance-0.5.0.tgz#cc237e65791c75dba856ace8971b94d7adcbc60b" - integrity sha512-E+L18eJKshr/ijnWZMexEEddwkp2T4Ye2dJSK4TcOKRYfrmfZJ95RRZ+MPNp1ES7RH2JYiyym1NIQKPcNNvhug== +"@firebase/performance@0.5.1": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@firebase/performance/-/performance-0.5.1.tgz#bb38ce1d98faba4e1c88530cc2af53cfecb58b7e" + integrity sha512-O93Yry8KhAaFrhnmBaMkM0lpgVmpd7CRX0eq1S0IKLdE3MdF+oAtbQiZG/NuRl3Vz8vjoz96R6bPbCWaDuiy8Q== dependencies: - "@firebase/component" "0.5.6" - "@firebase/installations" "0.5.0" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" + "@firebase/component" "0.5.7" + "@firebase/installations" "0.5.1" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/polyfill@0.3.36": @@ -1750,16 +1757,16 @@ promise-polyfill "8.1.3" whatwg-fetch "2.0.4" -"@firebase/remote-config-compat@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@firebase/remote-config-compat/-/remote-config-compat-0.1.0.tgz#8eb2582d1909dd4d5023383e43d73ad605d56daa" - integrity sha512-PpCh5f5hUUaDCmiJsuu/u9a0g0G5WH3YSbfH1jPejVOaJ1lS82615E7WOzco4zMllLYfX62VaUYD2vvcLyXE/w== +"@firebase/remote-config-compat@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@firebase/remote-config-compat/-/remote-config-compat-0.1.1.tgz#8ff028e53b1f0b6c482257a5da371c7dea9928d3" + integrity sha512-ZHRHYTdDztXHxgYXzuuD6Goa6ScmAqtctXl2eC6D8vxA8fIGRQKHN+9AMwxm8b3JHzdVY/5XhAOmKCcFvPOgtw== dependencies: - "@firebase/component" "0.5.6" - "@firebase/logger" "0.2.6" - "@firebase/remote-config" "0.2.0" + "@firebase/component" "0.5.7" + "@firebase/logger" "0.3.0" + "@firebase/remote-config" "0.3.0" "@firebase/remote-config-types" "0.2.0" - "@firebase/util" "1.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/remote-config-types@0.2.0": @@ -1767,26 +1774,26 @@ resolved "https://registry.yarnpkg.com/@firebase/remote-config-types/-/remote-config-types-0.2.0.tgz#1e2759fc01f20b58c564db42196f075844c3d1fd" integrity sha512-hqK5sCPeZvcHQ1D6VjJZdW6EexLTXNMJfPdTwbD8NrXUw6UjWC4KWhLK/TSlL0QPsQtcKRkaaoP+9QCgKfMFPw== -"@firebase/remote-config@0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@firebase/remote-config/-/remote-config-0.2.0.tgz#aa2bd7b34e0e40a259c3f0409a5084864f234f0f" - integrity sha512-hNZ+BqsTmfe8ogpeow95NSwQmKIeetKdPxKpyC6RZBeFUae782+2HrUx4/Quep6OZjOHQF6xZ5d3VOxu2ZKEfg== +"@firebase/remote-config@0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@firebase/remote-config/-/remote-config-0.3.0.tgz#43faf34eeb7407f7660eeca2790ccab25f76903d" + integrity sha512-Yf9/iXToC6Kbec1yOQ9mdTc1MP0mR2VCCR/n3Q+Ol3U+PML+ePXfqWiL2VHrUA86BeB2hpXF1BcTxvD4uOiDnA== dependencies: - "@firebase/component" "0.5.6" - "@firebase/installations" "0.5.0" - "@firebase/logger" "0.2.6" - "@firebase/util" "1.3.0" + "@firebase/component" "0.5.7" + "@firebase/installations" "0.5.1" + "@firebase/logger" "0.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" -"@firebase/storage-compat@0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@firebase/storage-compat/-/storage-compat-0.1.2.tgz#98e6b3516a70799935618c32e6b8937370587929" - integrity sha512-eff0e2qcDX188mqr7aKrqr4TIS25/cE6E7Xo9WRLe3c17nqGgmrYM4DDS3VDttNbf1j5XaoEnZVZafE9/BR3Rg== +"@firebase/storage-compat@0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@firebase/storage-compat/-/storage-compat-0.1.3.tgz#74a579aac6dc6e2c8293c8bdebb93bbcff0e0da9" + integrity sha512-m2htGJjCFlTONsqYRKXTfzkux3nbhpIpd72RK2iPkRPE69nQ0wiVplIE7bCaq3CSFMbkI3ETOtTTfW1wrOpF2g== dependencies: - "@firebase/component" "0.5.6" - "@firebase/storage" "0.8.2" + "@firebase/component" "0.5.7" + "@firebase/storage" "0.8.3" "@firebase/storage-types" "0.6.0" - "@firebase/util" "1.3.0" + "@firebase/util" "1.4.0" tslib "^2.1.0" "@firebase/storage-types@0.6.0": @@ -1794,14 +1801,14 @@ resolved "https://registry.yarnpkg.com/@firebase/storage-types/-/storage-types-0.6.0.tgz#0b1af64a2965af46fca138e5b70700e9b7e6312a" integrity sha512-1LpWhcCb1ftpkP/akhzjzeFxgVefs6eMD2QeKiJJUGH1qOiows2w5o0sKCUSQrvrRQS1lz3SFGvNR1Ck/gqxeA== -"@firebase/storage@0.8.2": - version "0.8.2" - resolved "https://registry.yarnpkg.com/@firebase/storage/-/storage-0.8.2.tgz#e08c05d070a468f0976a3d0cd32318655f0ae3b7" - integrity sha512-I9mVYhQ/DkWI1MKHhYvI4dnguXdXC50S5ryehOcR/JmSwyYjh1+T+IFQp0hHb1VWTixShzWoSGo1PhbrolFmIA== +"@firebase/storage@0.8.3": + version "0.8.3" + resolved "https://registry.yarnpkg.com/@firebase/storage/-/storage-0.8.3.tgz#49bdfb47a1b136eebf884e7343038d8f3437f08c" + integrity sha512-oraycQ787tEr6xu2Qc4nngLz1YEoEjZ+lrjThx0CJZB7VwdlkIJ24TkzJ9xoeWc+cpo34deg/If4w8AU5/WupQ== dependencies: - "@firebase/component" "0.5.6" - "@firebase/util" "1.3.0" - node-fetch "2.6.1" + "@firebase/component" "0.5.7" + "@firebase/util" "1.4.0" + node-fetch "2.6.2" tslib "^2.1.0" "@firebase/util@1.2.0": @@ -1811,17 +1818,17 @@ dependencies: tslib "^2.1.0" -"@firebase/util@1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@firebase/util/-/util-1.3.0.tgz#e71113bdd5073e9736ceca665b54d9f6df232b20" - integrity sha512-SESvmYwuKOVCZ1ZxLbberbx+9cnbxpCa4CG2FUSQYqN6Ab8KyltegMDIsqMw5KyIBZ4n1phfHoOa22xo5NzAlQ== +"@firebase/util@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@firebase/util/-/util-1.4.0.tgz#81e985adba44b4d1f21ec9f5af9628d505891de8" + integrity sha512-Qn58d+DVi1nGn0bA9RV89zkz0zcbt6aUcRdyiuub/SuEvjKYstWmHcHwh1C0qmE1wPf9a3a+AuaRtduaGaRT7A== dependencies: tslib "^2.1.0" -"@firebase/webchannel-wrapper@0.5.1": - version "0.5.1" - resolved "https://registry.yarnpkg.com/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.5.1.tgz#a64d1af3c62e3bb89576ec58af880980a562bf4e" - integrity sha512-dZMzN0uAjwJXWYYAcnxIwXqRTZw3o14hGe7O6uhwjD1ZQWPVYA5lASgnNskEBra0knVBsOXB4KXg+HnlKewN/A== +"@firebase/webchannel-wrapper@0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.6.0.tgz#e18ea901c84917f8dadd0185048a9d00573fe595" + integrity sha512-Pz4+7HPzKvOFI1ICQ6pyUv/VgStEWq9IGiVaaV1cQLi66NIA1mD5INnY4CDNoVAxlkuZvDEUZ+cVHLQ8iwA2hQ== "@gar/promisify@^1.0.1": version "1.1.2" @@ -6234,6 +6241,13 @@ faye-websocket@0.11.3, faye-websocket@^0.11.3: dependencies: websocket-driver ">=0.5.1" +faye-websocket@0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + fecha@^4.2.0: version "4.2.1" resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce" @@ -6469,37 +6483,37 @@ firebase-tools@^9.0.0: winston-transport "^4.4.0" ws "^7.2.3" -firebase@^9.0.0: - version "9.0.2" - resolved "https://registry.yarnpkg.com/firebase/-/firebase-9.0.2.tgz#092019326f1c9a67ec00ec78d50f80244581c705" - integrity sha512-+wdsD3Sk3fOgplzv4yzBmJ3Pdr01QiFF38Zq+8hzd+Dv6ZKMrgiq5CRljCaWenhZ/j8nuvHlq82u64ZARaXC+w== - dependencies: - "@firebase/analytics" "0.7.0" - "@firebase/analytics-compat" "0.1.1" - "@firebase/app" "0.7.0" - "@firebase/app-check" "0.4.0" - "@firebase/app-check-compat" "0.1.1" - "@firebase/app-compat" "0.1.1" +firebase@^9.1.0: + version "9.1.1" + resolved "https://registry.yarnpkg.com/firebase/-/firebase-9.1.1.tgz#a2980cf397cdbf9933430576c0413ec5c30e2f62" + integrity sha512-106PqKLwWo4vINQUwEbk2aU/nAFhRbCBE2IdnQmf7UDaW4wqJGZcgRvy3jSyuZr/dkqnT7ymKX0GGrDSzNLU6g== + dependencies: + "@firebase/analytics" "0.7.1" + "@firebase/analytics-compat" "0.1.2" + "@firebase/app" "0.7.2" + "@firebase/app-check" "0.4.1" + "@firebase/app-check-compat" "0.1.2" + "@firebase/app-compat" "0.1.3" "@firebase/app-types" "0.7.0" - "@firebase/auth" "0.17.2" - "@firebase/auth-compat" "0.1.2" - "@firebase/database" "0.12.0" - "@firebase/database-compat" "0.1.0" - "@firebase/firestore" "3.0.2" - "@firebase/firestore-compat" "0.1.2" - "@firebase/functions" "0.7.1" - "@firebase/functions-compat" "0.1.2" - "@firebase/installations" "0.5.0" - "@firebase/messaging" "0.9.0" - "@firebase/messaging-compat" "0.1.0" - "@firebase/performance" "0.5.0" - "@firebase/performance-compat" "0.1.0" + "@firebase/auth" "0.18.1" + "@firebase/auth-compat" "0.1.4" + "@firebase/database" "0.12.1" + "@firebase/database-compat" "0.1.1" + "@firebase/firestore" "3.1.0" + "@firebase/firestore-compat" "0.1.3" + "@firebase/functions" "0.7.2" + "@firebase/functions-compat" "0.1.3" + "@firebase/installations" "0.5.1" + "@firebase/messaging" "0.9.1" + "@firebase/messaging-compat" "0.1.1" + "@firebase/performance" "0.5.1" + "@firebase/performance-compat" "0.1.1" "@firebase/polyfill" "0.3.36" - "@firebase/remote-config" "0.2.0" - "@firebase/remote-config-compat" "0.1.0" - "@firebase/storage" "0.8.2" - "@firebase/storage-compat" "0.1.2" - "@firebase/util" "1.3.0" + "@firebase/remote-config" "0.3.0" + "@firebase/remote-config-compat" "0.1.1" + "@firebase/storage" "0.8.3" + "@firebase/storage-compat" "0.1.3" + "@firebase/util" "1.4.0" flat-arguments@^1.0.0: version "1.0.2" @@ -8451,7 +8465,7 @@ jszip@^3.1.3: readable-stream "~2.3.6" set-immediate-shim "~1.0.1" -jszip@^3.5.0, jszip@^3.6.0: +jszip@^3.6.0: version "3.7.1" resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.7.1.tgz#bd63401221c15625a1228c556ca8a68da6fda3d9" integrity sha512-ghL0tz1XG9ZEmRMcEN2vt7xabrDdqHHeykgARpmZ0BiIctWxM47Vt63ZO2dnp4QYt/xJVLLy5Zv1l/xRdh2byg== @@ -9781,7 +9795,19 @@ node-fetch-npm@^2.0.2: json-parse-better-errors "^1.0.0" safe-buffer "^5.1.1" -node-fetch@2.6.1, node-fetch@^2.3.0, node-fetch@^2.6.1: +node-fetch@2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.2.tgz#986996818b73785e47b1965cc34eb093a1d464d0" + integrity sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA== + +node-fetch@2.6.5: + version "2.6.5" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.5.tgz#42735537d7f080a7e5f78b6c549b7146be1742fd" + integrity sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ== + dependencies: + whatwg-url "^5.0.0" + +node-fetch@^2.3.0, node-fetch@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== @@ -12114,7 +12140,7 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" -rimraf@2, rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@^2.7.1: +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -12330,17 +12356,7 @@ selenium-webdriver@3.6.0, selenium-webdriver@^3.0.1: tmp "0.0.30" xml2js "^0.4.17" -selenium-webdriver@4.0.0-beta.1: - version "4.0.0-beta.1" - resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.0.0-beta.1.tgz#db645b0d775f26e4e12235db05796a1bc1e7efda" - integrity sha512-DJ10z6Yk+ZBaLrt1CLElytQ/FOayx29ANKDtmtyW1A6kCJx3+dsc5fFMOZxwzukDniyYsC3OObT5pUAsgkjpxQ== - dependencies: - jszip "^3.5.0" - rimraf "^2.7.1" - tmp "^0.2.1" - ws "^7.3.1" - -selenium-webdriver@^4.0.0-beta.2: +selenium-webdriver@4.0.0-rc-1, selenium-webdriver@^4.0.0-beta.2: version "4.0.0-rc-1" resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.0.0-rc-1.tgz#b1e7e5821298c8a071e988518dd6b759f0c41281" integrity sha512-bcrwFPRax8fifRP60p7xkWDGSJJoMkPAzufMlk5K2NyLPht/YZzR2WcIk1+3gR8VOCLlst1P2PI+MXACaFzpIw== @@ -13555,6 +13571,11 @@ toxic@^1.0.0: dependencies: lodash "^4.17.10" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + traceur@0.0.105: version "0.0.105" resolved "https://registry.yarnpkg.com/traceur/-/traceur-0.0.105.tgz#5cf9dee83d6b77861c3d6c44d53859aed7ab0479" @@ -14155,6 +14176,11 @@ webdriver-manager@^12.1.7: semver "^5.3.0" xml2js "^0.4.17" +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + webpack-dev-middleware@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.0.0.tgz#0abe825275720e0a339978aea5f0b03b140c1584" @@ -14301,6 +14327,14 @@ whatwg-fetch@2.0.4: resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + when@^3.7.5: version "3.7.8" resolved "https://registry.yarnpkg.com/when/-/when-3.7.8.tgz#c7130b6a7ea04693e842cdc9e7a1f2aa39a39f82" @@ -14446,7 +14480,7 @@ ws@^6.2.1: dependencies: async-limiter "~1.0.0" -ws@^7.2.3, ws@^7.3.1: +ws@^7.2.3: version "7.5.5" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881" integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w== From a5f63d32cde83f6b0cd3748549021b9703f56d23 Mon Sep 17 00:00:00 2001 From: James Daniels Date: Tue, 5 Oct 2021 22:24:33 -0400 Subject: [PATCH 4/7] Fix modular user/screen tracking --- samples/advanced/src/app/app.module.ts | 6 +++- src/analytics/analytics.module.ts | 18 ++++++++---- src/analytics/screen-tracking.service.ts | 17 ++++++++++-- src/analytics/user-tracking.service.ts | 35 ++++++++++++++---------- src/schematics/utils.ts | 7 +++-- 5 files changed, 56 insertions(+), 27 deletions(-) diff --git a/samples/advanced/src/app/app.module.ts b/samples/advanced/src/app/app.module.ts index 0ca52a41f..b1818b687 100644 --- a/samples/advanced/src/app/app.module.ts +++ b/samples/advanced/src/app/app.module.ts @@ -19,6 +19,7 @@ import { StorageComponent } from './storage/storage.component'; import type { app } from 'firebase-admin'; import { AppCheckComponent } from './app-check/app-check.component'; +import { ScreenTrackingService, UserTrackingService } from '@angular/fire/analytics'; export const FIREBASE_ADMIN = new InjectionToken('firebase-admin'); @@ -57,7 +58,10 @@ export const FIREBASE_ADMIN = new InjectionToken('firebase-admin'); } }, [new Optional(), FIREBASE_ADMIN]), ], - providers: [ ], + providers: [ + UserTrackingService, + ScreenTrackingService, + ], bootstrap: [ ], }) export class AppModule { } diff --git a/src/analytics/analytics.module.ts b/src/analytics/analytics.module.ts index 521e302fb..3dfabd3c1 100644 --- a/src/analytics/analytics.module.ts +++ b/src/analytics/analytics.module.ts @@ -7,10 +7,14 @@ import { registerVersion } from 'firebase/app'; import { ScreenTrackingService } from './screen-tracking.service'; import { UserTrackingService } from './user-tracking.service'; -const PROVIDED_ANALYTICS_INSTANCES = new InjectionToken('angularfire2.analytics-instances'); +export const PROVIDED_ANALYTICS_INSTANCE_FACTORIES = new InjectionToken Analytics>>('angularfire2.analytics-instances.factory'); +export const PROVIDED_ANALYTICS_INSTANCES = new InjectionToken('angularfire2.analytics-instances'); const IS_SUPPORTED = new InjectionToken('angularfire2.analytics.isSupported'); -const isSupportedSymbol = Symbol('angularfire2.analytics.isSupported'); +const isSupportedValueSymbol = Symbol('angularfire2.analytics.isSupported.value'); +export const isSupportedPromiseSymbol = Symbol('angularfire2.analytics.isSupported'); + +globalThis[isSupportedPromiseSymbol] ||= isSupported().then(it => globalThis[isSupportedValueSymbol] = it); export function defaultAnalyticsInstanceFactory(isSupported: boolean, provided: FirebaseAnalytics[]|undefined, defaultApp: FirebaseApp) { if (!isSupported) { return null; } @@ -49,9 +53,9 @@ const DEFAULT_ANALYTICS_INSTANCE_PROVIDER = { ANALYTICS_INSTANCES_PROVIDER, { provide: APP_INITIALIZER, - useValue: () => isSupported().then(it => globalThis[isSupportedSymbol] = it), + useValue: () => globalThis[isSupportedPromiseSymbol], multi: true, - }, + } ] }) export class AnalyticsModule { @@ -68,7 +72,11 @@ export function provideAnalytics(fn: (injector: Injector) => FirebaseAnalytics, ngModule: AnalyticsModule, providers: [{ provide: IS_SUPPORTED, - useFactory: () => globalThis[isSupportedSymbol], + useFactory: () => globalThis[isSupportedValueSymbol], + }, { + provide: PROVIDED_ANALYTICS_INSTANCE_FACTORIES, + useValue: fn, + multi: true, }, { provide: PROVIDED_ANALYTICS_INSTANCES, useFactory: analyticsInstanceFactory(fn), diff --git a/src/analytics/screen-tracking.service.ts b/src/analytics/screen-tracking.service.ts index cc095447f..2f9cdfb74 100644 --- a/src/analytics/screen-tracking.service.ts +++ b/src/analytics/screen-tracking.service.ts @@ -1,14 +1,16 @@ -import { ComponentFactoryResolver, Injectable, NgZone, OnDestroy, Optional } from '@angular/core'; +import { Inject, ComponentFactoryResolver, Injectable, NgZone, OnDestroy, Optional, Injector } from '@angular/core'; import { of, Subscription, Observable } from 'rxjs'; import { distinctUntilChanged, filter, groupBy, map, mergeMap, pairwise, startWith, switchMap } from 'rxjs/operators'; import { ActivationEnd, Router, ɵEmptyOutletComponent } from '@angular/router'; import { Title } from '@angular/platform-browser'; import { VERSION } from '@angular/fire'; +import { FirebaseApp } from '@angular/fire/app'; import { registerVersion } from 'firebase/app'; import { Analytics } from './analytics'; import { logEvent } from './firebase'; import { UserTrackingService } from './user-tracking.service'; +import { analyticsInstanceFactory, defaultAnalyticsInstanceFactory, isSupportedPromiseSymbol, PROVIDED_ANALYTICS_INSTANCE_FACTORIES } from './analytics.module'; const FIREBASE_EVENT_ORIGIN_KEY = 'firebase_event_origin'; const FIREBASE_PREVIOUS_SCREEN_CLASS_KEY = 'firebase_previous_class'; @@ -146,21 +148,30 @@ export class ScreenTrackingService implements OnDestroy { private disposable: Subscription | undefined; constructor( - analytics: Analytics, @Optional() router: Router, @Optional() title: Title, componentFactoryResolver: ComponentFactoryResolver, zone: NgZone, @Optional() userTrackingService: UserTrackingService, + firebaseApp: FirebaseApp, + @Inject(PROVIDED_ANALYTICS_INSTANCE_FACTORIES) analyticsInstanceFactories: Array<(injector: Injector) => Analytics>, + injector: Injector, ) { registerVersion('angularfire', VERSION.full, 'screen-tracking'); - if (!analytics || !router) { return this; } + if (!router) { return this; } + // Analytics is not ready to be injected yet, as the APP_INITIALIZER hasn't evulated yet, do this the hard way + const analyticsInstance: Promise = globalThis[isSupportedPromiseSymbol].then((isSupported: boolean) => { + const analyticsInstances = analyticsInstanceFactories.map(fn => analyticsInstanceFactory(fn)(zone, isSupported, injector)); + return defaultAnalyticsInstanceFactory(isSupported, analyticsInstances, firebaseApp); + }); zone.runOutsideAngular(() => { this.disposable = ɵscreenViewEvent(router, title, componentFactoryResolver).pipe( switchMap(async params => { if (userTrackingService) { await userTrackingService.initialized; } + const analytics = await analyticsInstance; + if (!analytics) { return; } return logEvent(analytics, SCREEN_VIEW_EVENT, params); }) ).subscribe(); diff --git a/src/analytics/user-tracking.service.ts b/src/analytics/user-tracking.service.ts index 5d6cb04d8..1c6387afe 100644 --- a/src/analytics/user-tracking.service.ts +++ b/src/analytics/user-tracking.service.ts @@ -1,10 +1,12 @@ -import { Injectable, NgZone, OnDestroy } from '@angular/core'; +import { Inject, Injectable, Injector, NgZone, OnDestroy } from '@angular/core'; import { Analytics } from './analytics'; import { Subscription } from 'rxjs'; import { VERSION } from '@angular/fire'; import { Auth, authState } from '@angular/fire/auth'; import { registerVersion } from 'firebase/app'; import { setUserId } from './firebase'; +import { analyticsInstanceFactory, defaultAnalyticsInstanceFactory, isSupportedPromiseSymbol, PROVIDED_ANALYTICS_INSTANCE_FACTORIES } from './analytics.module'; +import { FirebaseApp } from '@angular/fire/app'; @Injectable() export class UserTrackingService implements OnDestroy { @@ -13,24 +15,27 @@ export class UserTrackingService implements OnDestroy { private readonly disposables: Array = []; constructor( - analytics: Analytics, auth: Auth, zone: NgZone, + @Inject(PROVIDED_ANALYTICS_INSTANCE_FACTORIES) analyticsInstanceFactories: Array<(injector: Injector) => Analytics>, + injector: Injector, + firebaseApp: FirebaseApp, ) { registerVersion('angularfire', VERSION.full, 'user-tracking'); - if (analytics) { - let resolveInitialized: () => void; - this.initialized = zone.runOutsideAngular(() => new Promise(resolve => { resolveInitialized = resolve; })); - this.disposables = [ - // TODO add credential tracking back in - authState(auth).subscribe(user => { - resolveInitialized(); - setUserId(analytics, user?.uid); - }), - ]; - } else { - this.initialized = Promise.reject(); - } + // Analytics is not ready to be injected yet, as the APP_INITIALIZER hasn't evulated yet, do this the hard way + const analyticsInstance: Promise = globalThis[isSupportedPromiseSymbol].then((isSupported: boolean) => { + const analyticsInstances = analyticsInstanceFactories.map(fn => analyticsInstanceFactory(fn)(zone, isSupported, injector)); + return defaultAnalyticsInstanceFactory(isSupported, analyticsInstances, firebaseApp); + }); + let resolveInitialized: () => void; + this.initialized = zone.runOutsideAngular(() => new Promise(resolve => { resolveInitialized = resolve; })); + this.disposables = [ + // TODO add credential tracking back in + authState(auth).subscribe(user => { + analyticsInstance.then(analytics => analytics && setUserId(analytics, user?.uid)); + resolveInitialized(); + }), + ]; } ngOnDestroy() { diff --git a/src/schematics/utils.ts b/src/schematics/utils.ts index 8b29fce0f..5d300329a 100644 --- a/src/schematics/utils.ts +++ b/src/schematics/utils.ts @@ -3,7 +3,7 @@ import { FirebaseRc, Workspace, WorkspaceProject, FirebaseApp, DeployOptions, FE import { join } from 'path'; import { SchematicsException, Tree } from '@angular-devkit/schematics'; import ts from '@schematics/angular/third_party/github.com/Microsoft/TypeScript/lib/typescript'; -import { findNode, addImportToModule, insertImport } from '@schematics/angular/utility/ast-utils'; +import { findNode, addImportToModule, addProviderToModule, insertImport } from '@schematics/angular/utility/ast-utils'; import { InsertChange, ReplaceChange, applyToUpdateRecorder, Change } from '@schematics/angular/utility/change'; import { buildRelativePath } from '@schematics/angular/utility/find-module'; import { overwriteIfExists } from './common'; @@ -217,10 +217,11 @@ export function addToNgModule(host: Tree, options: { sourcePath: string, feature options.features.includes(FEATURES.Analytics) && !findNode(source, ts.SyntaxKind.Identifier, 'provideAnalytics') ) { - // TODO add user and screen tracking service changes.push( - insertImport(source, modulePath, ['provideAnalytics', 'getAnalytics'] as any, '@angular/fire/analytics'), + insertImport(source, modulePath, ['provideAnalytics', 'getAnalytics', 'ScreenTrackingService', 'UserTrackingService'] as any, '@angular/fire/analytics'), ...addImportToModule(source, modulePath, `provideAnalytics(() => getAnalytics())`, null as any), + ...addProviderToModule(source, modulePath, `ScreenTrackingService`, null as any), + ...addProviderToModule(source, modulePath, `UserTrackingService`, null as any), ); } From 1d8a9eb709f7ab956687744ca21a62ba50d0b9b2 Mon Sep 17 00:00:00 2001 From: James Daniels Date: Tue, 5 Oct 2021 22:31:35 -0400 Subject: [PATCH 5/7] Dont double run tests on PRs --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 01b7bba09..c6600386d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,7 +3,7 @@ name: Test and publish on: push: branches: - - "**" + - master paths-ignore: - "**/*.md" pull_request: From bdc5b0d0791c9fd6d6574763fb6b4c1c5f2f35cc Mon Sep 17 00:00:00 2001 From: James Daniels Date: Tue, 5 Oct 2021 22:53:36 -0400 Subject: [PATCH 6/7] Clean up global AppCheck hack --- src/app-check/app-check.module.ts | 17 ++++++++++------- src/app-check/app-check.ts | 1 - src/auth/auth.ts | 1 - src/core.ts | 15 --------------- 4 files changed, 10 insertions(+), 24 deletions(-) diff --git a/src/app-check/app-check.module.ts b/src/app-check/app-check.module.ts index 0a1c6cc7b..0250f1e29 100644 --- a/src/app-check/app-check.module.ts +++ b/src/app-check/app-check.module.ts @@ -4,6 +4,7 @@ import { ɵgetDefaultInstanceOf, ɵAngularFireSchedulers, VERSION } from '@angul import { AppCheck, AppCheckInstances, APP_CHECK_PROVIDER_NAME } from './app-check'; import { FirebaseApps, FirebaseApp } from '@angular/fire/app'; import { registerVersion } from 'firebase/app'; +import { isPlatformServer } from '@angular/common'; export const PROVIDED_APP_CHECK_INSTANCES = new InjectionToken('angularfire2.app-check-instances'); export const APP_CHECK_NAMESPACE_SYMBOL = Symbol('angularfire2.app-check.namespace'); @@ -13,15 +14,16 @@ export function defaultAppCheckInstanceFactory(provided: FirebaseAppCheck[]|unde return defaultAppCheck && new AppCheck(defaultAppCheck); } +const LOCALHOSTS = ['localhost', '0.0.0.0', '127.0.0.1']; +const isLocalhost = typeof window !== 'undefined' && LOCALHOSTS.includes(window.location.hostname); + export function appCheckInstanceFactory(fn: (injector: Injector) => FirebaseAppCheck) { - return (zone: NgZone, injector: Injector) => { - // This isn't supported by the JS SDK yet, I've put in the feature request - // for the time being I've written a hack in core.ts - /* if (typeof process !== 'undefined' && process.env?.FIREBASE_APPCHECK_DEBUG_TOKEN) { - globalThis.FIREBASE_APPCHECK_DEBUG_TOKEN ??= process.env.FIREBASE_APPCHECK_DEBUG_TOKEN; - } else if (isDevMode()) { + // tslint:disable-next-line:ban-types + return (zone: NgZone, injector: Injector, platformId: Object) => { + // Node should use admin token provider, browser devmode and localhost should use debug token + if (!isPlatformServer(platformId) && (isDevMode() || isLocalhost)) { globalThis.FIREBASE_APPCHECK_DEBUG_TOKEN ??= true; - } */ + } const appCheck = zone.runOutsideAngular(() => fn(injector)); return new AppCheck(appCheck); }; @@ -66,6 +68,7 @@ export function provideAppCheck(fn: (injector: Injector) => FirebaseAppCheck, .. deps: [ NgZone, Injector, + PLATFORM_ID, ɵAngularFireSchedulers, FirebaseApps, ...deps, diff --git a/src/app-check/app-check.ts b/src/app-check/app-check.ts index 77050f853..2db67ca3a 100644 --- a/src/app-check/app-check.ts +++ b/src/app-check/app-check.ts @@ -19,7 +19,6 @@ export class AppCheck { export interface AppCheckInstances extends Array {} export class AppCheckInstances { - // tslint:disable-next-line:ban-types constructor() { return ɵgetAllInstancesOf(APP_CHECK_PROVIDER_NAME); } diff --git a/src/auth/auth.ts b/src/auth/auth.ts index f8d0f72d1..bf13ea337 100644 --- a/src/auth/auth.ts +++ b/src/auth/auth.ts @@ -19,7 +19,6 @@ export class Auth { export interface AuthInstances extends Array {} export class AuthInstances { - // tslint:disable-next-line:ban-types constructor() { return ɵgetAllInstancesOf(AUTH_PROVIDER_NAME); } diff --git a/src/core.ts b/src/core.ts index 6b959c704..6fb7db8fd 100644 --- a/src/core.ts +++ b/src/core.ts @@ -9,21 +9,6 @@ interface FirebaseAppWithContainer extends FirebaseApp { container: ComponentContainer; } -const LOCALHOSTS = ['localhost', '0.0.0.0', '127.0.0.1']; - -// HACK HACK HACK -// AppCheck stuff, here so we can get a jump on it. It's too late in the evaluation -// if we do this in the app-check module. globalThis.ngDevMode allows me to test if -// Angular is in DevMode before Angular initializes. -// Only do this in the browser, for Node we have the admin sdk -if (( - typeof process === 'undefined' || !process.versions?.node -) && ( - globalThis.ngDevMode || typeof window !== 'undefined' && LOCALHOSTS.includes(window.location.hostname) -)) { - globalThis.FIREBASE_APPCHECK_DEBUG_TOKEN ??= true; -} - export function ɵgetDefaultInstanceOf(identifier: string, provided: T[]|undefined, defaultApp: FirebaseApp): T|undefined { if (provided) { // Was provide* only called once? If so grab that From 876da2de7597b6801f33b490452974d872040e04 Mon Sep 17 00:00:00 2001 From: James Daniels Date: Tue, 5 Oct 2021 23:08:43 -0400 Subject: [PATCH 7/7] Depend on firebase-tools ^9.9.0 peer, optionally --- samples/advanced/src/app/app.module.ts | 2 +- src/package.json | 6 +++++- src/schematics/firebaseTools.ts | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/samples/advanced/src/app/app.module.ts b/samples/advanced/src/app/app.module.ts index b1818b687..d7e29138f 100644 --- a/samples/advanced/src/app/app.module.ts +++ b/samples/advanced/src/app/app.module.ts @@ -43,7 +43,7 @@ export const FIREBASE_ADMIN = new InjectionToken('firebase-admin'); FunctionsModule, provideFirebaseApp(() => initializeApp(environment.firebase)), provideAppCheck((injector) => { - const admin = injector.get(FIREBASE_ADMIN, null); + const admin = injector.get(FIREBASE_ADMIN, null); if (admin) { const provider = new CustomProvider({ getToken: () => admin. diff --git a/src/package.json b/src/package.json index 0da32eeb0..ad85dbc0e 100644 --- a/src/package.json +++ b/src/package.json @@ -32,7 +32,11 @@ "@schematics/angular": "^12.0.0", "firebase": "^9.0.0", "rxfire": "^6.0.0", - "rxjs": "~6.6.0" + "rxjs": "~6.6.0", + "firebase-tools": "^9.9.0" + }, + "peerDependenciesMeta": { + "firebase-tools": { "optional": true } }, "dependencies": { "tslib": "^2.0.0", diff --git a/src/schematics/firebaseTools.ts b/src/schematics/firebaseTools.ts index 5ed2606a6..bc89da809 100644 --- a/src/schematics/firebaseTools.ts +++ b/src/schematics/firebaseTools.ts @@ -41,8 +41,8 @@ export const getFirebaseTools = () => globalThis.firebaseTools ? globalThis.firebaseTools = firebaseTools; const version = firebaseTools.cli.version(); console.log(`Using firebase-tools version ${version}`); - if (parseInt(version, 10) !== 9) { - console.error('firebase-tools version 9 is required'); + if (parseFloat(version) < 9.9) { + console.error('firebase-tools version 9.9+ is required, please upgrade'); return Promise.reject(); } return firebaseTools;