版本記錄
版本號 | 時間 |
---|---|
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
都有一個名為ref
的Firebase
引用屬性,并且在該引用上調用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
])
下面就是詳細說明:
- 1) 找到用戶使用
cellForRow(at :)
點擊的單元格。 - 2) 使用索引路徑的行獲取相應的
GroceryItem
。 - 3) 在
grocery item
上標記completed
狀態。 - 4) 調用
toggleCellCheckbox(_:isCompleted :)
來更新單元格的可視屬性。 - 5) 使用
updateChildValues(_ :)
,傳遞字典,以更新Firebase
。 此方法與setValue(_ :)
不同,因為它僅應用更新,而setValue(_ :)
是破壞性的,并替換該引用處的整個值。
建立并運行。 點擊一個項目,看它在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
順序排列,因此completed
的key
將傳遞給查詢。 然后,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!)
}
}
下面進行詳細說明:
- 1) 從
alert controller
獲取用戶提供的電子郵件和密碼。 - 2) 在默認的
Firebase auth
對象上調用createUser(withEmail:password :)
,傳遞電子郵件和密碼。 - 3) 如果沒有錯誤,則表示已創建用戶帳戶。 但是,您仍需要對此新用戶進行身份驗證,因此請調用
signIn(withEmail:password :)
,再次傳遞提供的電子郵件和密碼。
建立并運行。 點擊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) 使用
addStateDidChangeListener(_ :)
創建一個身份驗證觀察者。 該塊傳遞兩個參數:auth
和user
。 - 2) 測試
user
的值。 成功進行用戶身份驗證后,將為user
填充用戶的信息。 如果身份驗證失敗,則變量為nil
。 - 3) 成功驗證后,執行
segue
并清除文本字段的文本。 你沒有將用戶傳遞給下一個控制器可能看起來很奇怪,但你會看到如何在GroceryListTableViewController.swift
中獲取它。
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)")
}
}
下面進行詳細說明:
- 1) 首先獲取
currentUser
并使用其uid
創建onlineRef
,uid
是表示用戶的唯一標識符。 - 2) 您調用
removeValue
來刪除onlineRef
的值。 Firebase會在登錄時自動將用戶添加到online
,但在注銷時不會刪除用戶。 相反,它只會在用戶斷開連接時將其刪除。 對于此應用程序,在用戶注銷后將其顯示為online
沒有意義,因此您可以在此處手動刪除它們。 - 3) 在完成閉包中,首先檢查是否有錯誤,如果是這樣,只需打印它。
- 4) 您在此處調用
Auth.auth().signOut()
以從鑰匙串中刪除用戶的憑據。 如果沒有錯誤,則關閉視圖控制器。 否則,您打印出錯誤。
構建并運行,點擊左側導航項,按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) 使用用戶的
uid
創建子引用,該引用是在Firebase創建帳戶時生成的。 - 2) 使用此參考來保存當前用戶的電子郵件。
- 3) 在
currentUserRef
上調用onDisconnectRemoveValue()
。 這會在與Firebase
的連接關閉后刪除引用位置的值,例如當用戶退出您的應用時。 這非常適合監控已下線的用戶。
建立并運行。 加載視圖時,當前用戶的電子郵件將作為子項添加到在線位置。
很好! 現在是時候在用戶數量增加時更改條形按鈕項的數量了。
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)
})
下面進行詳細分解:
- 1) 創建一個偵聽添加到
usersRef
管理的位置的子節點的觀察者。 這與值偵聽器不同,因為只有添加的子節點傳遞給閉包。 - 2) 從快照中獲取值,然后將其附加到本地陣列。
- 3) 當前行始終是本地數組的計數減1,因為表視圖管理的索引是從零開始的。
- 4) 使用計算的行索引創建實例
NSIndexPath
。 - 5) 使用動畫插入行,從而使單元格從頂部插入。
這只會在添加項目時呈現項目,而不是重新加載整個列表,它還使您能夠指定一個漂亮的動畫。
由于用戶可以脫機,因此表格也需要對被刪除的用戶做出反應。 在剛剛添加的代碼下面添加以下內容:
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基本使用簡介,感興趣的給個贊或者關注~~~