Skip to content

Commit 31087b8

Browse files
add delete user and reauthenticate methods
1 parent 1983e73 commit 31087b8

2 files changed

Lines changed: 60 additions & 5 deletions

File tree

FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ public final class AuthService {
8787
private let googleProvider: GoogleProviderProtocol?
8888
private let facebookProvider: FacebookProviderProtocol?
8989
private let phoneAuthProvider: PhoneAuthProviderProtocol?
90+
private var signedInCredential: AuthCredential?
9091

9192
private var safeGoogleProvider: GoogleProviderProtocol {
9293
get throws {
@@ -160,6 +161,7 @@ public final class AuthService {
160161
} else {
161162
do {
162163
try await auth.signIn(with: credentials)
164+
signedInCredential = credentials
163165
updateAuthenticationState()
164166
} catch {
165167
authenticationState = .unauthenticated
@@ -180,6 +182,40 @@ public final class AuthService {
180182
}
181183
}
182184

185+
// MARK: - User API
186+
187+
extension Date {
188+
func isWithinPast(minutes: Int) -> Bool {
189+
let calendar = Calendar.current
190+
guard let timeAgo = calendar.date(byAdding: .minute, value: -minutes, to: Date()) else {
191+
return false
192+
}
193+
return self >= timeAgo && self <= Date()
194+
}
195+
}
196+
197+
public extension AuthService {
198+
func reauthenticate() async throws {
199+
if let user = auth.currentUser, let credential = signedInCredential {
200+
try await user.reauthenticate(with: credential)
201+
}
202+
}
203+
204+
func deleteUser() async throws {
205+
do {
206+
if let user = auth.currentUser, let lastSignInDate = user.metadata.lastSignInDate {
207+
let needsReauth = !lastSignInDate.isWithinPast(minutes: 5)
208+
if needsReauth {
209+
try await reauthenticate()
210+
}
211+
try await user.delete()
212+
}
213+
} catch {
214+
throw error
215+
}
216+
}
217+
}
218+
183219
// MARK: - Email/Password Sign In
184220

185221
public extension AuthService {
@@ -193,6 +229,8 @@ public extension AuthService {
193229

194230
do {
195231
try await auth.createUser(withEmail: email, password: password)
232+
let credential = EmailAuthProvider.credential(withEmail: email, password: password)
233+
signedInCredential = credential
196234
updateAuthenticationState()
197235
} catch {
198236
authenticationState = .unauthenticated

FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/SignedInView.swift

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,38 @@ import SwiftUI
22

33
public struct SignedInView {
44
@Environment(AuthService.self) private var authService
5+
@State private var errorMessage = ""
56
}
67

78
extension SignedInView: View {
89
public var body: some View {
910
VStack {
1011
Text("Signed in")
1112
Text("User: \(authService.currentUser?.email ?? "Unknown")")
12-
Button("Sign out") {
13-
Task {
14-
try? await authService.signOut()
15-
}
16-
}
13+
1714
if authService.currentUser?.isEmailVerified == false {
1815
VerifyEmailView()
1916
}
2017
}
18+
Button("Sign out") {
19+
Task {
20+
do {
21+
try await authService.signOut()
22+
} catch {
23+
errorMessage = error.localizedDescription
24+
}
25+
}
26+
}
27+
Divider()
28+
Button("Delete account") {
29+
Task {
30+
do {
31+
try await authService.deleteUser()
32+
} catch {
33+
errorMessage = error.localizedDescription
34+
}
35+
}
36+
}
37+
Text(errorMessage).foregroundColor(.red)
2138
}
2239
}

0 commit comments

Comments
 (0)