js css html

基于Firebase平台开发(四) —— Firebase基本使

2019-02-01  本文已影响44人  刀客传奇

版本记录

版本号 时间
V1.0 2019.02.01 星期五

前言

Firebase是一家实时后端数据库创业公司,它能帮助开发者很快的写出Web端和移动端的应用。自2014年10月Google收购Firebase以来,用户可以在更方便地使用Firebase的同时,结合Google的云服务。Firebase能让你的App从零到一。也就是说它可以帮助手机以及网页应用的开发者轻松构建App。通过Firebase背后负载的框架就可以简单地开发一个App,无需服务器以及基础设施。接下来几篇我们就一起看一下基于Firebase平台的开发。感兴趣的看下面几篇文章。
1. 基于Firebase平台开发(一) —— 基于ML Kit的iOS图片中文字的识别(一)
2. 基于Firebase平台开发(二) —— 基于ML Kit的iOS图片中文字的识别(二)
3. 基于Firebase平台开发(三) —— Firebase基本使用简介(一)

Removing Items From the Table View

table view将同步对您的数据进行的任何类型的更改,但是当用户决定不获取该比萨饼时,现在无法更新Firebase

要通知数据库删除,您需要设置Firebase引用以在用户将其擦除时删除项目。

找到tableView(_:commit:forRowAt :)。 现在,此方法使用索引路径的行从本地数组中删除杂货项目。 它有效,但有更好的方法。 用以下内容替换现有实现:

if editingStyle == .delete {
  let groceryItem = items[indexPath.row]
  groceryItem.ref?.removeValue()
}

Firebase遵循单向数据流模型,因此viewDidLoad()中的侦听器会向应用程序通知购物清单的最新值。 删除项目会触发值更改。

索引路径的行用于检索相应的杂货项目。 每个GroceryItem都有一个名为refFirebase引用属性,并且在该引用上调用removeValue()会导致您在viewDidLoad()中定义的侦听器触发。 侦听器附加了一个闭包,它使用最新数据重新加载表视图。

建立并运行。 滑动某个项目,点击删除,然后在您的应用和Firebase中观看它消失。

干得好! 您的商品现在可以实时删除。


Checking Off Items

现在你知道了如何添加,删除和同步项目,这一切都非常酷。 但是当你真正购物时呢? 你应该删除你已经拥有的东西,还是在将它们添加到你的购物篮时标记它们会更好?

点击时,项目应变为灰色并显示复选标记,以便向用户提供一些不再需要该项目的视觉反馈。

打开GroceryListTableViewController.swift并找到toggleCellCheckbox(_:isCompleted :)。 此方法切换UITableViewCell的必要视图属性,具体取决于其关联项是否完整。

首次加载表视图时从tableView(_:cellForRowAtIndexPath :)调用它,当用户点击一行时从tableView(_:didSelectRowAt :)调用它。

用以下内容替换tableView(_:didSelectRowAt :)的当前实现:

// 1
guard let cell = tableView.cellForRow(at: indexPath) else { return }
// 2
let groceryItem = items[indexPath.row]
// 3
let toggledCompletion = !groceryItem.completed
// 4
toggleCellCheckbox(cell, isCompleted: toggledCompletion)
// 5
groceryItem.ref?.updateChildValues([
  "completed": toggledCompletion
])

下面就是详细说明:

建立并运行。 点击一个项目,看它在complete状态和incomplete状态之间来回切换。

恭喜你,你现在有了一个非常可爱的购物清单应用程序!


Sorting the Grocery List

如果选中的项目自动移动到列表的底部,则应用程序将更加强大10倍。 然后剩余的物品将清晰,易于您的眼睛看到。

使用Firebase queries,您可以按任意属性对列表进行排序。 仍在GroceryListTableViewController.swift中工作,更新viewDidLoad()中的观察者,如下所示:

ref.queryOrdered(byChild: "completed").observe(.value, with: { snapshot in
  var newItems: [GroceryItem] = []
  for child in snapshot.children {
    if let snapshot = child as? DataSnapshot,
       let groceryItem = GroceryItem(snapshot: snapshot) {
      newItems.append(groceryItem)
    }
  }
  
  self.items = newItems
  self.tableView.reloadData()
})

要按completed的值对数据进行排序,请在Firebase引用上调用queryOrdered(byChild :),该引用需要一个键才能按顺序排序。

由于列表需要按completed顺序排列,因此completedkey将传递给查询。 然后,queryOrdered(byChild :)返回一个引用,通知服务器以有序的方式返回数据。

建立并运行。 点击一行以切换其completion状态。 完成的项目神奇地移动到列表的底部。

哇! 你真的在这里买杂货。 看起来它应该足够简单,可以跨多个用户同步数据,例如,与重要的其他用户或室友同步。 这听起来像......认证的工作!


Authenticating Users

Firebase具有身份验证服务,允许应用程序通过多个providers进行身份验证。 您可以使用Google,Twitter,Facebook,Github,电子邮件和密码,匿名甚至自定义后端对用户进行身份验证。 在这里,您将使用电子邮件和密码,因为它是最容易设置的。

要启用电子邮件和密码身份验证,请转到Firebase dashboard,然后单击Authentication

选择SIGN-IN METHOD选项卡,然后在Sign-in providers部分中,选择Email/Password行。 单击Enable开关,然后单击SAVE

Firebase将凭证存储在钥匙串中,因此最后一步是通过导航到目标Capabilities并切换钥匙串共享来启用Xcode中的Keychain Sharing

在Xcode提示时,选择您的开发团队。 这是必需的,因此Xcode可以为您管理签名并自动启用App ID的功能。
现在,您已准备好使用他们的电子邮件和密码对用户进行身份验证!


Registering Users

LoginViewController.swift中,找到signUpDidTouch(_ :)。 这提供了一个允许用户注册帐户的UIAlertController。 找到saveAction并将以下内容添加到其闭包中:

// 1
let emailField = alert.textFields![0]
let passwordField = alert.textFields![1]

// 2
Auth.auth().createUser(withEmail: emailField.text!, password: passwordField.text!) { user, error in
  if error == nil {
    // 3
    Auth.auth().signIn(withEmail: self.textFieldLoginEmail.text!,
                       password: self.textFieldLoginPassword.text!)
  }
}

下面进行详细说明:

建立并运行。 点击Sign up按钮并输入电子邮件和密码,然后点击保存。 尚未成功登录时,视图控制器将无法导航到任何内容。 如果您刷新Firebase的Login & Auth标签,您将看到新创建的用户。

W00T!该应用程序现在注册用户,然后让他们登录。但是,不要庆祝,您需要完成该过程,以便人们可以按预期实际使用该应用程序。


Logging Users In

注册按钮可以注册并登录用户。 但是,Login按钮实际上无效,因为不执行身份验证。

仍然在LoginViewController.swift中工作,找到loginDidTouch(_ :)并用以下内容替换它的实现:

guard
  let email = textFieldLoginEmail.text,
  let password = textFieldLoginPassword.text,
  email.count > 0,
  password.count > 0
  else {
    return
}

Auth.auth().signIn(withEmail: email, password: password) { user, error in
  if let error = error, user == nil {
    let alert = UIAlertController(title: "Sign In Failed",
                                  message: error.localizedDescription,
                                  preferredStyle: .alert)
    
    alert.addAction(UIAlertAction(title: "OK", style: .default))
    
    self.present(alert, animated: true, completion: nil)
  }
}

此代码将在用户尝试通过点击Login按钮登录时对用户进行身份验证。

现在,只有在用户登录时才需要将segue执行到下一个控制器。


Observing Authentication State

Firebase具有允许您监视用户身份验证状态的观察者。 这是一个执行segue的好地方。

将以下内容添加到LoginViewController

override func viewDidLoad() {
  super.viewDidLoad()
  
  // 1
  Auth.auth().addStateDidChangeListener() { auth, user in
    // 2
    if user != nil {
      // 3
      self.performSegue(withIdentifier: self.loginToList, sender: nil)
      self.textFieldLoginEmail.text = nil
      self.textFieldLoginPassword.text = nil
    }
  }
}

下面进行详细说明:

1. Setting the User in the Grocery List

转到GroceryListTableViewController.swift,并将以下内容添加到viewDidLoad()的底部:

Auth.auth().addStateDidChangeListener { auth, user in
  guard let user = user else { return }
  self.user = User(authData: user)
}

在此处,您将身份验证观察者附加到Firebase auth对象,该对象在用户成功登录时又会分配user属性。

建立并运行。 如果用户已登录,则会绕过LoginViewController并转到GroceryListTableViewController。 当用户添加项目时,他们的电子邮件将显示在单元格的详细信息中。


Logging Users Out

由于用户可以登录,因此他们也应该能够注销。 打开OnlineUsers TableViewController.swift并用以下代码替换signoutButtonPressed(_ :)中的代码:

// 1
let user = Auth.auth().currentUser!
let onlineRef = Database.database().reference(withPath: "online/\(user.uid)")

// 2
onlineRef.removeValue { (error, _) in

  // 3
  if let error = error {
    print("Removing online failed: \(error)")
    return
  }

  // 4
  do {
    try Auth.auth().signOut()
    self.dismiss(animated: true, completion: nil)
  } catch (let error) {
    print("Auth sign out failed: \(error)")
  }
}

下面进行详细说明:

构建并运行,点击左侧导航项,按Sign Out,您将返回登录页面。

成功! 该应用程序现在具有基本用户身份验证。


Monitoring Users’ Online Status

现在该应用程序具有用户身份验证,是时候检测哪些用户在线。 打开GroceryListTableViewController.swift并添加以下属性:

let usersRef = Database.database().reference(withPath: "online")

这是Firebase参考,指向存储在线用户列表的在线位置。

接下来,将以下内容添加到viewDidLoad()内的addStateDidChangeListener(_ :)闭包的底部:

// 1
let currentUserRef = self.usersRef.child(self.user.uid)
// 2
currentUserRef.setValue(self.user.email)
// 3
currentUserRef.onDisconnectRemoveValue()

下面详细分解:

建立并运行。 加载视图时,当前用户的电子邮件将作为子项添加到在线位置。

很好! 现在是时候在用户数量增加时更改条形按钮项的数量了。

1. Updating the Online User Count

仍在GroceryListTableViewController.swift中,将以下代码添加到viewDidLoad()

usersRef.observe(.value, with: { snapshot in
  if snapshot.exists() {
    self.userCountBarButtonItem?.title = snapshot.childrenCount.description
  } else {
    self.userCountBarButtonItem?.title = "0"
  }
})

这将创建一个用于监视在线用户的观察者。 当用户上线和离线时,userCountBarButtonItem的标题将使用当前用户计数进行更新。


Displaying a List of Online Users

打开OnlineUsersTableViewController.swift,就像之前一样,在类的属性部分中添加对Firebase的在线用户记录的本地引用:

let usersRef = Database.database().reference(withPath: "online")

viewDidLoad()中,替换:

currentUsers.append("hungry@person.food")

使用下面的代码

// 1
usersRef.observe(.childAdded, with: { snap in
  // 2
  guard let email = snap.value as? String else { return }
  self.currentUsers.append(email)
  // 3
  let row = self.currentUsers.count - 1
  // 4
  let indexPath = IndexPath(row: row, section: 0)
  // 5
  self.tableView.insertRows(at: [indexPath], with: .top)
})

下面进行详细分解:

这只会在添加项目时呈现项目,而不是重新加载整个列表,它还使您能够指定一个漂亮的动画。

由于用户可以脱机,因此表格也需要对被删除的用户做出反应。 在刚刚添加的代码下面添加以下内容:

usersRef.observe(.childRemoved, with: { snap in
  guard let emailToFind = snap.value as? String else { return }
  for (index, email) in self.currentUsers.enumerated() {
    if email == emailToFind {
      let indexPath = IndexPath(row: index, section: 0)
      self.currentUsers.remove(at: index)
      self.tableView.deleteRows(at: [indexPath], with: .fade)
    }
  }
})

这只是添加了一个观察者,它监听被删除的usersRef引用的子节点。 它在本地数组中搜索电子邮件值以查找相应的子项,一旦找到,它将从表中删除关联的行。

建立并运行。

Firebase用户信息中心中点按Online,当前用户的电子邮件将显示在表格中。 使用一些技巧,可以将用户添加到Online,一旦你这样做,它就会显示在列表中。 单击仪表板中的Remove按钮,用户将消失。

添加和删除用户时,表会更新。


Enabling Offline

杂货店以不稳定的数据连接而臭名昭着。 你认为他们现在都有Wi-Fi,没有!

没问题,您只需设置数据库即可脱机工作。 打开AppDelegate.swift并将以下内容添加到application(_:didFinishLaunchingWithOptions:)return true之前:

Database.database().isPersistenceEnabled = true

是的,就是这样! 就像您的应用程序脱机工作一样。 一旦建立连接,即使跨应用重新启动发生的离线更新也将应用于您的Firebase数据库。

在整个Firebase教程中,您通过构建协作式购物清单应用程序了解了Firebase的基础知识。 您已实施将数据保存到Firebase数据库,实时同步数据,验证用户身份,监控在线用户状态以及启用脱机支持。 而且你没有编写一行服务器代码就完成了所有这些!

要了解有关Firebase的更多信息,请查看Firebase自己提供的文档和示例(documentation)。

后记

本篇主要讲述了Firebase基本使用简介,感兴趣的给个赞或者关注~~~

上一篇下一篇

猜你喜欢

热点阅读