Last active
September 28, 2020 15:13
-
-
Save alx-andru/1d75830ef6e0325fdbb3b89bf146475d to your computer and use it in GitHub Desktop.
Code experiment to resolve "unknown method" due to proxy polyfill in IE11
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
Injectable, | |
Inject, | |
Optional, | |
NgZone, | |
PLATFORM_ID, | |
} from "@angular/core"; | |
import { Observable, of, from } from "rxjs"; | |
import { | |
switchMap, | |
map, | |
observeOn, | |
shareReplay, | |
first, | |
tap, | |
} from "rxjs/operators"; | |
import { | |
FIREBASE_OPTIONS, | |
FIREBASE_APP_NAME, | |
FirebaseOptions, | |
FirebaseAppConfig, | |
ɵPromiseProxy, | |
ɵlazySDKProxy, | |
ɵfirebaseAppFactory, | |
ɵAngularFireSchedulers, | |
ɵkeepUnstableUntilFirstFactory, | |
} from "@angular/fire"; | |
import { User, auth } from "firebase/app"; | |
import { isPlatformServer } from "@angular/common"; | |
export interface AngularFireAuth extends ɵPromiseProxy<auth.Auth> {} | |
@Injectable({ | |
providedIn: "any", | |
}) | |
export class AngularFireAuth { | |
/** | |
* Observable of authentication state; as of Firebase 4.0 this is only triggered via sign-in/out | |
*/ | |
public readonly authState: Observable<User | null>; | |
/** | |
* Observable of the currently signed-in user's JWT token used to identify the user to a Firebase service (or null). | |
*/ | |
public readonly idToken: Observable<string | null>; | |
/** | |
* Observable of the currently signed-in user (or null). | |
*/ | |
public readonly user: Observable<User | null>; | |
/** | |
* Observable of the currently signed-in user's IdTokenResult object which contains the ID token JWT string and other | |
* helper properties for getting different data associated with the token as well as all the decoded payload claims | |
* (or null). | |
*/ | |
public readonly idTokenResult: Observable<auth.IdTokenResult | null>; | |
constructor( | |
@Inject(FIREBASE_OPTIONS) options: FirebaseOptions, | |
@Optional() | |
@Inject(FIREBASE_APP_NAME) | |
nameOrConfig: string | FirebaseAppConfig | null | undefined, | |
// tslint:disable-next-line:ban-types | |
@Inject(PLATFORM_ID) platformId: Object, | |
zone: NgZone | |
) { | |
const schedulers = new ɵAngularFireSchedulers(zone); | |
const keepUnstableUntilFirst = ɵkeepUnstableUntilFirstFactory(schedulers); | |
const auth = of(undefined).pipe( | |
observeOn(schedulers.outsideAngular), | |
switchMap(() => zone.runOutsideAngular(() => import("firebase/auth"))), | |
map(() => ɵfirebaseAppFactory(options, zone, nameOrConfig)), | |
map((app) => zone.runOutsideAngular(() => app.auth())), | |
shareReplay({ bufferSize: 1, refCount: false }) | |
); | |
if (isPlatformServer(platformId)) { | |
this.authState = this.user = this.idToken = this.idTokenResult = of(null); | |
} else { | |
// HACK, as we're exporting auth.Auth, rather than auth, developers importing firebase.auth | |
// (e.g, `import { auth } from 'firebase/app'`) are getting an undefined auth object unexpectedly | |
// as we're completely lazy. Let's eagerly load the Auth SDK here. | |
// There could potentially be race conditions still... but this greatly decreases the odds while | |
// we reevaluate the API. | |
const _ = auth.pipe(first()).subscribe(); | |
this.authState = auth.pipe( | |
switchMap((auth) => auth.getRedirectResult().then(() => auth)), | |
switchMap((auth) => | |
zone.runOutsideAngular( | |
() => | |
new Observable<User | null>(auth.onAuthStateChanged.bind(auth)) | |
) | |
), | |
keepUnstableUntilFirst | |
); | |
this.user = auth.pipe( | |
switchMap((auth) => auth.getRedirectResult().then(() => auth)), | |
switchMap((auth) => | |
zone.runOutsideAngular( | |
() => new Observable<User | null>(auth.onIdTokenChanged.bind(auth)) | |
) | |
), | |
keepUnstableUntilFirst | |
); | |
this.idToken = this.user.pipe( | |
switchMap((user) => (user ? from(user.getIdToken()) : of(null))) | |
); | |
this.idTokenResult = this.user.pipe( | |
switchMap((user) => (user ? from(user.getIdTokenResult()) : of(null))) | |
); | |
} | |
const klass = Object.assign({ signInWithPopup: null, signOut: null }, this); | |
return ɵlazySDKProxy(klass, auth, zone); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment