티스토리 뷰

반응형

로그인도 Auth의 signIn 함수면 간단히 끝 -! 

 

FirebaseManager에 다음메소드를 추가하고 

  class func login(email: String, password: String, completion: @escaping (Result<AuthDataResult,Error>) -> Void) {
      Auth.auth().signIn(withEmail: email, password: password) { (result, error) in
          if let result = result {
              completion(.success(result))
          } else if let error = error {
              completion(.failure(error))
          }
      }
  }

 

LoginViewModel도 구현해준다 

struct LoginViewModel {
    struct State {
        
    }
    
    struct Action {
        let login = PublishSubject<(String, String)>()
    }
    
    let state = State()
    let action = Action()
    private let bag = DisposeBag()
    
    init() {
        action.login.subscribe(onNext: { email, password in
            FirebaseManager.login(email: email, password: password, completion: { result in
                switch result {
                case .success(let success):
                    let navController = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "MemosNavController")
                    Navigator.present(to: navController)
                    print(success.user.email)
                case .failure(let failure):
                    Navigator.presentAlert(with: failure.localizedDescription)
                }
            })
        }).disposed(by: bag)
    }
}

 

Navigator에 present메소드도 추가해줬다 

    class func present(to viewController: UIViewController, animated: Bool = false, completion: (() -> Void)? = nil) {
        UIApplication.topViewController()?.present(viewController, animated: animated, completion: completion)
    }

 

 

그러면 로그인 실패하면 alert화면,

 로그인 성공하면 메모 화면으로 가게 된다 

 

로그인한 사용자에 따라 다르게 메모를 보여주기 위해 FirebaseManager 코드를 다음과 같이 바꿔준다

User 노드 밑에 메모들이 추가되는 구조이다 

 

 

class FirebaseManager {
    
    class var user: String {
        return Auth.auth().currentUser?.email?.removeSpecialCharacters() ?? ""
    }
    
    class func add(memo: Memo) {
        let rootRef = Database.database().reference()
        let memosRef = rootRef.child(user).child("memos")
        
        let memoRef = memosRef.childByAutoId()
        memoRef.setValue(memo.toDictionary())
    }
    
    class func fetchAll() -> Observable<[Memo]> {
        return Observable<[Memo]>.create { observer in
            let rootRef = Database.database().reference()
            rootRef.child(user).child("memos").observe(.value) { snapshot in
                var memos: [Memo] = []
                let memosDic = snapshot.value as? [String: Any] ?? [:]
                for (key, _) in memosDic.sorted(by: {$0.key < $1.key}) {
                    if let memoDic = memosDic[key] as? [String: Any], let memo = Memo(dic: memoDic, ID: key) {
                        memos.append(memo)
                    }
                }
                observer.onNext(memos)
            }
            return Disposables.create()
        }
    }
    
    class func delete(key: String) {
        let rootRef = Database.database().reference()
        let memoRef = rootRef.child(user).child("memos").child(key)
        memoRef.removeValue()
    }
    
    class func change(key: String, to memo: Memo) {
        let rootRef = Database.database().reference()
        let memoRef = rootRef.child(user).child("memos").child(key)
        memoRef.setValue(memo.toDictionary())
    }
}

 

extension String {
    func removeSpecialCharacters() -> String {
        return self.components(separatedBy: CharacterSet.letters.inverted).joined()
    }
}

이 string extension도 해줬는데, 노드의 키값으로 특수문자가 들어가는 것을 빼주기 위해 사용했다

이메일을 그대로 쓰면 이런 에러가 나기 때문...!! 

 

'(child:) Must be a non-empty string and not contain '.' '#' '$' '[' or ']'' 

 

 

반응형
댓글