If I create a user in Firestore Auth console and then login via app it’s fine. However, if I create a user via my app, log out, and then attempt to login – it throws the following error and I’m not logged in.
Any help would be appreciated thank you. I’m not so familiar with Firebase. I have been following this tutorial.
Error:
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}
RegistrationView
import SwiftUI
struct RegisterView: View {
@EnvironmentObject var viewModel: AuthViewModel
@State var email: String = ""
@State var name: String = ""
@State var password: String = ""
var body: some View {
VStack(alignment: .leading) {
Text("Register")
//
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)
}
}
}
}
}
LoginView
import SwiftUI
struct LoginView: View {
@EnvironmentObject var viewModel: AuthViewModel
@State var email: String = ""
@State var password: String = ""
var body: some View {
NavigationStack {
VStack(alignment: .leading) {
Text("Login")
//
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()
}
}
}
}
}
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, 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() {
}
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)
}
}