Firebase AUthentication은 firebase에서 제공하는 사용자 인증 시스템이다. 이메일, 비밀번호를 통한 개인 로그인 외에도 Google, Facebook 같은 소셜 로그인도 쉽게 할 수 있어 바로 적용하여 로그인, 회원가입을 구현을 위해 사용했다.
func loginUser() {
Auth.auth().signIn(withEmail: userEmail, password: userPassword) { result, err in
if let err = err {
print("로그인 실패!", err)
return
}
print("로그인 성공!\(result?.user.uid ?? "")")
}
}
func createNewAccount(confirmPassword: String) {
if userPassword == confirmPassword {
Auth.auth().createUser(withEmail: userEmail, password: userPassword) { result, err in
if let err = err {
self.resultText = .failure
print("계정 생성 실패: ", err)
return
}
self.resultText = .success
print("계정 생성 성공\(result?.user.uid ?? "")")
}
} else {
print("비밀번호가 일치하지 않습니다.")
}
}
이렇게 하면 Firebase 서버에 사용자의 이메일과 비밀번호가 저장되며, 이 정보는 암호화되어 안전하게 보관되고 이후에 사용자가 로그인하면 Firebase는 이 정보를 확인하여 사용자를 인증하게 된다.

Singleton 패턴은 특정 클래스의 인스턴스가 하나만 존재하도록 보장하는 디자인 패턴이다. 이 패턴은 여러 곳에서 동일한 리소스에 접근하거나 동일한 작업을 수행할 때 유용하다.
예를 들어, 현재 앱 뷰모델의 코드에서 FirebaseAuthentication 클래스는 Singleton 패턴을 사용하고 있다. 이 클래스의 인스턴스는 앱 전체에서 단 하나 only one만 존재하며, 이를 통해 사용자의 이메일과 비밀번호 같은 인증 정보를 안전하게 관리하고 있다.
이 클래스의 메소드들은 사용자의 로그인 상태를 관리하는데 필요한 작업을 수행합니다. 이들 메소드는 앱의 어느 곳에서나 동일한 인증 정보에 접근하거나 수정할 수 있어야 하므로, Singleton 패턴이 이러한 요구 사항을 충족시키는 데 매우 유용하고 이를 통해 코드의 일관성을 유지하고 리소스의 효율적인 사용을 가능하게 한다.
Singleton 패턴은 앱 전체에서 공유되어야 하는 리소스나 서비스에 대한 중앙 집중식(global) 접근을 제공
하지만 Singleton 인스턴스가 너무 많은 작업을 처리하거나 많은 데이터를 저장하게 되면, 앱의 다른 부분들과의 강한 결합(tight coupling)이 발생할 수 있고, 이는 앱의 유지 보수를 어렵게 만들 수 있으므로, Singleton 패턴을 적절히 사용하는 것이 중요한 포인트.
class FirebaseAuthentication: ObservableObject {
// FirebaseAuthentication 클래스의 인스턴스를 하나만 생성하도록 보장하는 Singleton 패턴
static let shared = FirebaseAuthentication()
// 사용자의 이메일과 비밀번호를 저장하고 관리하는 변수들
@Published var userEmail: String = ""
@Published var userPassword: String = ""
// 비밀번호 표시 여부를 저장하고 관리하는 변수
@Published var isPasswordVisible: Bool = false
// 계정 생성 결과를 저장하고 관리하는 변수
@Published var resultText: AccountCreationResult?
// 외부에서 인스턴스를 생성하지 못하도록 private으로 선언된 생성자
private init() {}
...
}