【问题标题】:Uncaught (in promise): FirebaseError未捕获(承诺):FirebaseError
【发布时间】:2021-11-15 03:04:58
【问题描述】:

我收到以下错误。我的问题是 NOT 与实际错误,而是说错误是 Uncaught。如果您查看我的 auth.service.tssign-in.component.ts 文件,我会发现错误。

我的问题是,为什么在控制台中出现 Error: Uncaught (in promise) 错误?我错过了什么?

我正在使用
"@angular/fire": "^7.0.4"
"firebase": "^9.0.2"
"rxjs": "6.6.7"

auth.service.ts

    /**
     * Sign in
     *
     * @param credentials
     */
    signIn(credentials: { email: string; password: string }): Promise<any> 
    {
        return this.auth.signInWithEmailAndPassword(credentials.email, credentials.password)
            .then((userCredential) => {
                
                // Signed in 
                const user = userCredential.user;
                //console.log(user);

                // Store the access token in the local storage
                userCredential.user.getIdToken().then(token => {
                    this.accessToken = token;
                    //console.log(token);
                })

                // Set the authenticated flag to true
                this._authenticated = true;

                // Store the user on the user service
                //this._userService.user = user;

                // ...
            })
            .catch((error) => {
                const errorCode = error.code;
                const errorMessage = error.message;
                console.log('Show Error', error.code);
                throw errorCode;
            });
    }

登录.component.ts

    /**
     * Sign in
     */
    signIn(): void
    {
        // Return if the form is invalid
        if ( this.signInForm.invalid )
        {
            return;
        }

        // Disable the form
        this.signInForm.disable();

        // Hide the alert
        this.showAlert = false;

        // Sign in
        this._authService.signIn(this.signInForm.value)
            .then(
                () => {

                    // Set the redirect url.
                    // The '/signed-in-redirect' is a dummy url to catch the request and redirect the user
                    // to the correct page after a successful sign in. This way, that url can be set via
                    // routing file and we don't have to touch here.
                    const redirectURL = this._activatedRoute.snapshot.queryParamMap.get('redirectURL') || '/signed-in-redirect';

                    // Navigate to the redirect url
                    this._router.navigateByUrl(redirectURL);

                },
                (response) => {

                    console.log('error from auth.service', response);

                    // Re-enable the form
                    this.signInForm.enable();

                    // Reset the form
                    this.signInNgForm.resetForm();

                    // Set the alert
                    this.alert = {
                        type   : 'error',
                        message: 'Wrong email or password'
                    };

                    // Show the alert
                    this.showAlert = true;
                }
            );
    }

【问题讨论】:

  • 你再次抛出错误throw errorCode;,乍一看我没有看到处理该错误的代码。
  • 请原谅我的无知,但我该如何解决呢?
  • 不重新抛出它是一种选择。另一种是在调用堆栈中捕获更高的重新抛出错误,并在那里处理它而不重新抛出它。
  • 我删除了重新抛出并且错误没有返回到sign-in.component.ts。控制台仍然显示 firebase 错误。
  • 你能用代码告诉我如何处理吗?我将不胜感激

标签: javascript angular firebase firebase-authentication angularfire


【解决方案1】:

首先,我的母语不是英语,所以如果我写得像个傻瓜,你知道为什么。

试试这个:

_authService.service.ts

    import { getAuth, signInWithEmailAndPassword, Auth, inMemoryPersistence, browserLocalPersistence } from '@angular/fire/auth';


    constructor(private _fireAuth: Auth,) {

/**
 * Sign-in
 *
 * @param credentials
 * @param rememberMe
 */
    async signIn(credentials: { email: string; password: string }, rememberMe: boolean): Promise<any> {
        // firebase Persistence.LOCAL   browserLocalPersistence
        // firebase Persistence.SESSION browserSessionPersistence
        // firebase Persistence.NONE    inMemoryPersistence

        return new Promise(async (resolve, reject) => {
            //Initialize auth()
            const auth = getAuth();

            // Extra function
            if (rememberMe) {
                await getAuth().setPersistence(browserLocalPersistence).catch(error => reject(-1));
            } else {
                await getAuth().setPersistence(inMemoryPersistence).catch(error => reject(-1));
            }

            signInWithEmailAndPassword(auth, credentials.email, credentials.password).then(async (userCredential) => {
                // Signed in 
                const user = userCredential.user;
                console.log(user);

                // Store the access token in the local storage
                await userCredential.user.getIdTokenResult().then(token => {
                    this.accessToken = token.token;
                    console.log(token);
                })

                // Set the authenticated flag to true
                this._authenticated = true;
            }).catch(error => reject(error.code));
        });
    }

注意: 如您所见,我添加了一些额外功能,如果您不感兴趣,可以删除(setPersistence),这允许您考虑用户选择保持登录状态,如果他想要,或者在他关闭标签时删除他的登录信息。

sign-in.component.ts

alert = {
        userNotFound : false,
        wrongPassword: false,
        unknownError : false,
};
    /**
     * Sign in
     */
    signIn(): void
    {
        // Return if the form is invalid
        if ( this.signInForm.invalid )
        {
            return;
    }

    // Disable the form
    this.signInForm.disable();

    // Hide the alert
    this.showAlert = false;

    // Sign in
    this._authService.signIn(this.signInForm.value)
        .then(
            () => {

                // Set the redirect url.
                // The '/signed-in-redirect' is a dummy url to catch the request and redirect the user
                // to the correct page after a successful sign in. This way, that url can be set via
                // routing file and we don't have to touch here.
                const redirectURL = this._activatedRoute.snapshot.queryParamMap.get('redirectURL') || '/signed-in-redirect';

                // Navigate to the redirect url
                this._router.navigateByUrl(redirectURL);

            },
            (response) => {

                console.log('error from auth.service', response);

                // Re-enable the form
                this.signInForm.enable();

                // Reset the form
                this.signInNgForm.resetForm();

                // Set the alert
                if (error === - 1) {
                this.alert.unknownError = true;
                } else if (error === 'auth/email-not-found' || error === 'auth/user-not-found') {
                this.alert.userNotFound = true;
                } else if (error === 'auth/wrong-password') {
                this.alert.wrongPassword = true;
                }
            }
        );
}

【讨论】:

  • 您的代码示例中有几个错误,但在我修复了这些错误之后,它就像一个魅力。谢谢楼主!!!
  • @LuisCabrera 请你告诉我错误在哪里,因为我或多或少使用这个表格。
  • 1) 在 _authService.service.ts 中您期望 2 个参数,但在 sing-in.component.ts 中只传递一个 2) 我无法使用您创建的警报对象
  • 3) 在 _authService.service.ts 我添加了 resolve(this._authenticated) 以返回对组件的调用
  • 啊,我看到了,只是在我的代码中我使用了 2 个值,我没有意识到,但是,如果您对 Angular 有更多疑问,它对您有用,很好火模块让我知道,因为没有太多更新的文档,祝我的朋友好运。
【解决方案2】:

正如弗兰克提到的那样,您正在抛出一个错误而没有在更高的水平上将其恢复,我会尝试这样做:

try {
  this._authService.signIn(this.signInForm.value)
            .then(
                () => {

                    // Set the redirect url.
                    // The '/signed-in-redirect' is a dummy url to catch the request and redirect the user
                    // to the correct page after a successful sign in. This way, that url can be set via
                    // routing file and we don't have to touch here.
                    const redirectURL = this._activatedRoute.snapshot.queryParamMap.get('redirectURL') || '/signed-in-redirect';

                    // Navigate to the redirect url
                    this._router.navigateByUrl(redirectURL);

                },
                (response) => {

                    console.log('error from auth.service', response);

                    // Re-enable the form
                    this.signInForm.enable();

                    // Reset the form
                    this.signInNgForm.resetForm();

                    // Set the alert
                    this.alert = {
                        type   : 'error',
                        message: 'Wrong email or password'
                    };

                    // Show the alert
                    this.showAlert = true;
                }
            );
} catch(e) {}

只需用try catch 块包围您的代码,这样错误就会被忽略。我没有测试它,但也许在then 之后调用另一个catch 方法可以解决问题,但它仍然处于同一级别(承诺级别),所以我不确定它是否会起作用。

【讨论】:

  • 感谢您的建议。我尝试按照您的建议添加try catch,但得到了相同的结果。然后我在then 之后尝试了另一种catch 方法,但又得到了同样的结果。其他想法?
  • 更新。我尝试在then 之后添加try catch 和额外的catch,但也没有用
  • @LuisCabrera 您确定您在此期间没有更改代码吗?
  • @LuisCabrera 你能创建一个堆栈闪电战来重现错误吗?
猜你喜欢
  • 2023-01-28
  • 2023-02-05
  • 1970-01-01
  • 2017-11-24
  • 2021-09-06
  • 2021-07-01
  • 1970-01-01
  • 2019-11-03
  • 2019-04-18
相关资源
最近更新 更多