gpt4 book ai didi

firebase - AngularFireAuth 模拟器登录在页面重新加载时丢失

转载 作者:行者123 更新时间:2023-12-03 17:32:18 24 4
gpt4 key购买 nike

我的 Angular 项目成功使用了 AngularFireAuth可从 @angular/fire 注入(inject)连接到本地 Firebase 身份验证模拟器。我使用这些资源作为我的实现的引用:

  • Firebase 文档:Instrument your app to talk to the Authentication emulator
  • 堆栈溢出:How to configure AngularFireAuthModule and/or AngularFireAuth to point to auth emulator

  • 但是,一旦我重新加载页面,登录状态就会丢失,我必须重新登录。
    首先,我尝试在 Angular 组件构造函数中设置这样的持久性:
    constructor( private _fireauth: AngularFireAuth) {
    this._fireAuth.useEmulator(`http://${location.hostname}:9099/`);
    this._fireauth.setPersistence(firebase.auth.Auth.Persistence.LOCAL);
    }
    这没有任何区别。然后我在浏览器网络控制台中注意到,显然firebase库确实在页面加载后找到了本地存储的 session ,但最初尝试联系谷歌服务器来验证它,这当然失败了,因为它是一个本地模拟器 session :
    enter image description here
    这似乎是有道理的,因为 _fireAuth.useEmulator()仅在组件构造函数中调用。应用程序的其他部分,例如 AngularFireAuthGuard可能会尝试更早地访问身份验证状态。几次尝试调用 useEmulator()在应用程序的任何其他部分可能尝试访问身份验证状态失败之前:
  • Attempt1:调用useEmulator()@Injectable({providedIn: 'root'})又名服务构造函数
  • Attempt2:提供 APP_INITIALIZER在应用程序启动之前执行代码:

  • export function initializeApp1(afa: AngularFireAuth): any {
    return () => {
    return new Promise(resolve => {
    afa.useEmulator(`http://${location.hostname}:9099/`);
    setTimeout(() => resolve(), 5000);
    });
    };
    }

    @NgModule({
    declarations: [
    ...
    ],
    imports: [
    ...,
    AngularFireModule.initializeApp(environment.firebase),
    AngularFireAuthModule,
    ...
    ],
    providers: [
    AngularFireAuth,
    {
    provide: APP_INITIALIZER,
    useFactory: initializeApp1,
    deps: [AngularFireAuth],
    multi: true
    }
    ],
    bootstrap: [AppComponent]
    })

  • Attempt3:提供USE_EMULATOR可注入(inject)的seems to be implementedAngularFireAuth构造函数:
  •   providers: [
    {
    provide: USE_EMULATOR,
    useValue: [location.hostname, 9099]
    },
    ]
    我特别想 Attempt3会尽可能早地设置模拟器模式,因为它可以比在构造函数中设置早多少? Injectable 似乎可以工作,因为浏览器控制台会在页面加载时打印通常的警告消息: auth.esm.js:133 WARNING: You are using the Auth Emulator, which is intended for local testing only. Do not use with production credentials. .但是,对 googleapis.com 的请求每次在页面加载时检测到本地 indexedDB 中的存储 session 时仍然会触发,之后我会注销。另外值得注意的是:在 Attempt2我使用 5 秒超时来显着减慢应用程序初始化和对 googleapis.com 的请求在页面加载后立即触发,在 Angular 完成初始化之前。
    在这一点上,我不知道该尝试什么了。 @angular/fire is obviously build upon the basic Firebase JavaScript library ,所以我可能不得不更早地设置模拟器模式,但也许我在这里走错了方向?
    ==================================================== ===============
    [编辑:] 似乎结合 Attempt 2Attempt 3有效,只要 initializeApp1()方法使用 setTimout()至少约。 100 毫秒。当我删除超时或将其设置为低至 10 毫秒时,登录就会丢失。任何超过 100 毫秒的超时也有效。在这一点上,它看起来很像比赛条件?
    工作示例:
    export function initializeApp1(afa: AngularFireAuth): any {
    return () => {
    return new Promise(resolve => {
    afa.useEmulator(`http://${location.hostname}:9099/`);
    setTimeout(() => resolve(), 100); // delay Angular initialization by 100ms
    });
    };
    }

    @NgModule({
    declarations: [
    ...
    ],
    imports: [
    ...,
    AngularFireModule.initializeApp(environment.firebase),
    AngularFireAuthModule,
    ...
    ],
    providers: [
    // Provide the AngularFireAuth constructor with the emulator parameters
    {
    provide: USE_EMULATOR,
    useValue: [location.hostname, 9099]
    },
    // Delay the app initialization process by 100ms
    {
    provide: APP_INITIALIZER,
    useFactory: initializeApp1,
    // for some reason this dependency is necessary for this solution to work.
    // Maybe in order to trigger the constructor *before* waiting 100ms?
    deps: [AngularFireAuth],
    multi: true
    }
    ],
    bootstrap: [AppComponent]
    })

    我还注意到 this commentAngularFireAuth源代码。到目前为止,我真的不明白发生了什么,但也许问题是相关的:

    // 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.

    最佳答案

    我已经在我的代码中调整了初始化应用程序函数,以使用 rxjs 而不是 Promise。

    export const initializeApp = (angularFireAuth: AngularFireAuth): (() => Observable<boolean>) => {
    if (!environment.firebaseConfig.useEmulator) {
    return () => of(true);
    } else {
    return () => of(true).pipe(
    delay(100),
    tap(_ => {
    angularFireAuth.useEmulator('http://localhost:9099/');
    })
    );
    }
    };

    关于firebase - AngularFireAuth 模拟器登录在页面重新加载时丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65025005/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com