我有一个已连接到 Firebase 并具有电子邮件/密码登录名的应用。但是,当我登录应用程序并关闭应用程序时,它不会保持登录状态。我尝试了其他线程中的一些操作(其中一个在我当前的代码中),但没有一个成功.任何帮助,谢谢!
登录电子邮件视图控制器:
import UIKit
import FirebaseAuth
class LoginEmailViewController: UIViewController {
let userDefault = UserDefaults.standard
let launchedBefore = UserDefaults.standard.bool(forKey: "isLoggedIn")
@IBOutlet weak var loginEmailTextField: UITextField!
@IBOutlet weak var loginPasswordTextField: UITextField!
@IBOutlet weak var loginButton: UIButton!
@IBOutlet weak var loginErrorLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
setUpElements()
}
func setUpElements() {
// hide error label
loginErrorLabel.alpha = 0
// style the textfields
Utilities.styleTextField(loginEmailTextField)
Utilities.styleTextField(loginPasswordTextField)
}
@IBAction func loginTapped(_ sender: Any) {
// TODO: Validate Text Fields
// Create cleaned versions of the text field
let email = loginEmailTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let password = loginPasswordTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
// Signing in the user
Auth.auth().signIn(withEmail: email, password: password) { (result, error) in
if error != nil {
// Couldn't sign in
self.loginErrorLabel.text = error!.localizedDescription
self.loginErrorLabel.alpha = 1
}
else {
// user signed in successfully, perform segue to tableViewController and set userDefault to true
print("User signed in")
self.userDefault.set(true, forKey: "isLoggedIn")
self.userDefault.synchronize()
let vc = UITableViewController()
vc.modalPresentationStyle = .fullScreen
self.performSegue(withIdentifier: "signInSegue", sender: nil)
self.present(vc, animated: true)
}
}
}
}
配置文件视图控制器:
import UIKit
import FirebaseAuth
class ProfileViewController: UIViewController {
let userDefault = UserDefaults.standard
let launchedBefore = UserDefaults.standard.bool(forKey: "isLoggedIn")
@IBOutlet var tableView: UITableView!
let data = ["Sign Out"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.delegate = self
tableView.dataSource = self
view.backgroundColor = .blue
}
}
extension ProfileViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = data[indexPath.row]
cell.textLabel?.textAlignment = .center
cell.textLabel?.textColor = .red
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let signOutAction = UIAlertAction(title: "Sign Out", style: .destructive) { (action) in
do {
try FirebaseAuth.Auth.auth().signOut()
// switch screen to welcome screen
self.userDefault.set(false, forKey: "isLoggedIn")
self.userDefault.synchronize()
let vc = WelcomeViewController()
vc.modalPresentationStyle = .fullScreen
self.performSegue(withIdentifier: "logOutSegue", sender: nil)
self.present(vc, animated: true)
print("Successfully logged out")
} catch let err {
print("Failed to log out", err)
Service.showAlert(on: self, style: .alert, title: "Sign Out Error", message: err.localizedDescription)
}
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
Service.showAlert(on: self, style: .actionSheet, title: nil, message: nil, actions: [signOutAction, cancelAction], completion: nil)
}
}
欢迎视图控制器:
import UIKit
class WelcomeViewController: UIViewController {
let userDefault = UserDefaults.standard
let launchedBefore = UserDefaults.standard.bool(forKey: "isLoggedIn")
@IBOutlet weak var signInFacebookButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// if user is already signed in, go to tabBarController screens
if userDefault.bool(forKey: "isLoggedIn") {
performSegue(withIdentifier: "currentUserSegue", sender: self)
return
}
setUpElements()
}
func setUpElements() {
let button = signInFacebookButton
button?.layer.borderWidth = 2
button?.layer.borderColor = UIColor.init(red: 93/255, green: 129/255, blue: 140/255, alpha: 1).cgColor
button?.layer.cornerRadius = 20.0
button?.tintColor = UIColor.black
}
}
“退出”按钮位于 ProfileViewController
内,“登录”按钮位于 LoginEmailViewController
内。单击“退出”后,将返回欢迎屏幕。
答案 0 :(得分:0)
Firebase 会在应用重新加载时自动恢复用户的身份验证状态。这是一个异步操作,因为它需要调用服务器,因此需要设置您的代码来处理此问题。
因此,如果您现在调用 signIn(withEmail: , password: )
来处理活动登录,您还需要调用以 addStateDidChangeListener
的形式处理身份验证状态的恢复。来自 determining the currently signed in user 的文档中有这个例子:
handle = Auth.auth().addStateDidChangeListener { (auth, user) in
// ...
}
如果您在应用程序启动时附加此侦听器,当 Firebase 客户端开始恢复状态时,它最初会以 null
为用户调用,然后一旦状态恢复,它将以实际触发用户对象。
在此回调中,您可以将用户分派到正确的屏幕以处理他们的状态。
答案 1 :(得分:0)
在@FrankVanPuffelen 的帮助下,我刚刚将其添加到我的 MainNavigationController
中:
// if user is already signed in, go to tabBarController screens
Auth.auth().addStateDidChangeListener { auth, user in
if user != nil {
// User is signed in. Show home screen
let tabBarC = self.storyboard?.instantiateViewController(withIdentifier: "mainTabBarController") as! TabBarController
tabBarC.modalPresentationStyle = .fullScreen
self.present(tabBarC, animated: false, completion: nil)
print("User signed in, switched to TabBarController")
} else {
// No User is signed in. Show user the login screen
let welcomeVC = self.storyboard?.instantiateViewController(withIdentifier: "welcomeViewController") as! WelcomeViewController
welcomeVC.modalPresentationStyle = .fullScreen
self.present(welcomeVC, animated: false, completion: nil)
print("No user signed in, switched to WelcomeViewController")
}
}
这可以无缝运行,而且非常简单!