使用Firebase Auth登出后无法重新登录的问题求助
问题描述
在Firestore Auth控制台创建的用户可通过应用正常登录,但通过应用创建用户、登出后再尝试登录时,会抛出错误无法完成登录。
错误信息
Error Domain=FIRAuthErrorDomain Code=17004 "The supplied auth credential is malformed or has expired." UserInfo={NSLocalizedDescription=The supplied auth credential is malformed or has expired., FIRAuthErrorUserInfoNameKey=ERROR_INVALID_CREDENTIAL}
相关代码
主应用代码
import SwiftUI import Firebase import Resolver class AppDelegate: NSObject, UIApplicationDelegate { func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil ) -> Bool { FirebaseApp.configure() return true } } @main struct quizApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate var body: some Scene { WindowGroup { SetupView() } } }
ContentView
import Resolver import SwiftUI extension Resolver: ResolverRegistering { public static func registerAllServices() { let model = AuthViewModel() register { model } } } struct ContentView: View { @InjectedObject var authViewModel: AuthViewModel var body: some View { if authViewModel.userSession != nil { AppTabView() } else { LoginView() } } }
RegistrationView
import Resolver import SwiftUI struct RegisterView: View { @InjectedObject var viewModel: AuthViewModel @State var name: String = "" @State var email: String = "" @State var password: String = "" var body: some View { List { TextField("Name", text: $name) TextField("Email", text: $email) .textInputAutocapitalization(.never) .keyboardType(.emailAddress) .textCase(.lowercase) SecureField("Password", text: $password) Spacer() Button("Sign Up") { Task { try await viewModel.register(name: name, email: email, password: email) } } } .navigationTitle("Register") } }
LoginView
import Resolver import SwiftUI struct LoginView: View { @InjectedObject var viewModel: AuthViewModel @State var email: String = "" @State var password: String = "" var body: some View { NavigationStack { List { TextField("Email", text: $email) .textInputAutocapitalization(.never) .keyboardType(.emailAddress) .textCase(.lowercase) SecureField("Password", text: $password) Spacer() Button("Login") { Task { try await viewModel.login(email: email, password: password) } } NavigationLink("Sign up") { RegisterView() } } .navigationTitle("Login") } } }
AuthViewModel
import SwiftUI import FirebaseAuth import FirebaseFirestoreSwift import FirebaseFirestore final class AuthViewModel: ObservableObject { @Published var userSession: FirebaseAuth.User? @Published var currentUser: User? init() { // Read from Firestore cache on device if logged in self.userSession = Auth.auth().currentUser } func login(email: String, password: String) async throws { do { let result = try await Auth.auth().signIn(withEmail: email, password: password) self.userSession = result.user try await fetch() } catch { print(error) } } func register(name: String, email: String, password: String) async throws { do { let result = try await Auth.auth().createUser(withEmail: email, password: password) self.userSession = result.user // let user = User(id: result.user.uid, name: name, jlptLevel: 5, email: email) let encodeUser = try Firestore.Encoder().encode(user) try await Firestore.firestore().collection("users").document(user.id).setData(encodeUser) // try await fetch() } catch { print("Failed to create user", error) } } func signout() { do { try Auth.auth().signOut() self.userSession = nil self.currentUser = nil } catch { print(error) } } func deleteAccount() { if let session = self.userSession { session.delete() self.userSession = nil self.currentUser = nil } } func fetch() async throws { guard let uid = Auth.auth().currentUser?.uid else { return } let snapshot = try await Firestore.firestore().collection("users").document(uid).getDocument() self.currentUser = try snapshot.data(as: User.self) } }
解决方案
问题出在RegistrationView的注册按钮逻辑里:
Button("Sign Up") { Task { try await viewModel.register(name: name, email: email, password: email) } }
这里调用注册方法时,错误地把email作为password参数传入,导致Firebase用邮箱字符串作为用户密码创建账号。但登录时你输入的是自己设置的密码,两者不匹配,就触发了ERROR_INVALID_CREDENTIAL错误。
只需把参数修正为正确的password即可:
Button("Sign Up") { Task { try await viewModel.register(name: name, email: email, password: password) } }
修改后重新测试,注册和登录流程就能正常运行。
内容的提问来源于stack exchange,提问作者lacking-cypher
相关产品推荐
相关产品推荐

