Firebase updatePassword调用报错:No overload matches this call
Angular中调用Firebase updatePassword出现TypeScript错误的解决方案
问题背景
在Angular组件实现密码更新功能时,调用Firebase的updatePassword方法触发TypeScript错误,提示No overload matches this call,具体包含两个问题:
- 传入的User类型与方法要求的类型不兼容,当前User缺少
linkAndRetrieveDataWithCredential等14个属性; newPassword参数类型为null | undefined,无法赋值给方法要求的string类型。
解决方案
1. 修复User类型不兼容问题
问题根源是@angular/fire与firebase核心库的类型定义不匹配,需要明确导入正确的User类型并确保依赖版本一致:
- 从
firebase/auth导入User类型,为auth.currentUser指定明确类型; - 检查
package.json中@angular/fire和firebase版本是否匹配(建议使用官方推荐的对应版本)。
2. 修复newPassword类型不匹配问题
虽然表单已经做了必填验证,但TypeScript无法自动推断updatePassword.value.newPassword为非空值,需要通过非空断言或类型守卫确保其为string类型:
- 利用表单已通过
!this.updatePassword.valid校验的前提,使用非空断言!标记newPassword为非空; - 或者添加类型守卫逻辑,确保值存在后再调用方法。
修改后的完整代码
import { Component } from '@angular/core'; import { FormControl, FormGroup, Validators } from '@angular/forms'; import { reauthenticateWithCredential, EmailAuthProvider, getAuth, updatePassword } from '@angular/fire/auth'; import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms'; import { FirebaseError } from '@firebase/util'; // 导入正确的User类型 import { User } from 'firebase/auth'; export class CustomValidators { static MatchValidator(source: string, target: string): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { const sourceCtrl = control.get(source); const targetCtrl = control.get(target); return sourceCtrl && targetCtrl && sourceCtrl.value !== targetCtrl.value ? { mismatch: true } : null; }; } } @Component({ selector: 'app-update-password', templateUrl: './update-password.component.html', styleUrls: ['./update-password.component.css'] }) export class UpdatePasswordComponent { constructor() { } passwordCharLen: number = 6 formErrStatus: boolean = false; errorMessage: string = "" updatePassword = new FormGroup( { currentPassword: new FormControl(null, [Validators.required, Validators.minLength(this.passwordCharLen)]), newPassword: new FormControl(null, [Validators.required, Validators.minLength(this.passwordCharLen)]), confirmNewPassword: new FormControl(null, [Validators.required, Validators.minLength(this.passwordCharLen)]), }, [CustomValidators.MatchValidator('newPassword', 'confirmNewPassword')] ); async updateAccountPassword(): Promise<boolean> { console.log('updatePassword:', this.updatePassword.value) if (!this.updatePassword.valid) { console.log('Form validation failed') console.log('form data: ', this.updatePassword) this.formErrStatus = true; this.errorMessage = "Please enter all above details."; return false } else { this.formErrStatus = false; this.errorMessage = ""; } if (this.updatePassword.value.currentPassword == this.updatePassword.value.newPassword) { this.formErrStatus = true; this.errorMessage = "New Password should be different from current password"; return false } const auth = getAuth() // 明确指定User类型 const user: User | null = auth.currentUser; const credential = EmailAuthProvider.credential( auth.currentUser?.email!, this.updatePassword.value.currentPassword! ) // 利用表单验证通过的前提,添加非空断言 const newPassword = this.updatePassword.value.newPassword! if (user) { try { await reauthenticateWithCredential(user, credential) } catch (error: unknown) { console.log('Got error in reauthenticate user:', error) if (error instanceof FirebaseError) { console.log('error code:', error.code) console.log('error message:', error.message) if (error.code == 'auth/wrong-password') { this.formErrStatus = true; this.errorMessage = "Invalid current password"; return false } } } console.log('user reauthenticate successfully.') try { await updatePassword(user, newPassword) } catch (error: unknown) { console.log('Error in updatePassword: ', error) } } return true } get passwordMatchError() { return ( this.updatePassword.getError('mismatch') && this.updatePassword.get('confirmNewPassword')?.touched ); } }
内容的提问来源于stack exchange,提问作者Suresh
相关产品推荐
相关产品推荐

