Firebase Tutorial: Getting Started 教程翻譯
備註: 本教程已由 Attila Hegedüs 更新適配 iOS 10 和 Swift 3,原教程由David East 創作。
原文:https://www.raywenderlich.com/139322/firebase-tutorial-getting-started-2
翻譯:JoeyChang 轉載請標明出處
原文:http://www.jianshu.com/p/c61d118c216c
Firebase 是一個移動後臺服務,它可以幫助我們建立具有優秀特性的移動 apps。Firebase 提供以下三個主要服務: a realtime database, user authentication and hosting。通過整合 Firebase iOS SDK, 你幾乎不用寫一行程式碼就能建立出非常棒的應用。
Firebase 具有資料庫實時性這樣的獨特效能。
你曾經使用過 pull-to-refresh 去拉新資料麼?有了 Firebase,現在你可以忽略那種重新整理資料方法了。
當 Firebase 資料庫更新時,所有的連線者可以實時獲取更新,這就意味著你的 app 可以不用使用者互動就能獲取資料庫當前最新值。
本篇 Firebase 教程中,我們將通過建立一個名叫 Grocr 的具有協作性的grocery list app , 來學習Firebase 的一些基本原理。當我們新增一個專案到列表時,它將實時出現在使用者的其它裝置中,但是我們並不滿足於此,我們還將調整 Grocr 讓它可以離線工作,以致即使僅有一個 grocery 資料連線,列表也能保持同步。
通過本文,你將學習到以下技能:
* 儲存資料到Firebase資料庫
* 從 Firebase 實時同步資料
* 驗證 users
* 線上監控 users
* 實現離線支援
開始,下載初始專案 Grocr-starter. 它使用 CocoaPods 管理 Firebase 。
在 Xcode 中開啟 Grocr.xcworkspace,該專案包含三個view controllers:
1. LoginViewController.swift.
現在登入功能還是使用的硬編碼 user credentials,稍後我們將優化它。
GroceryListTableViewController.swift.
這個 controller 是 UITableViewController 子類,它通過 UIAlertController 新增 items 到本地資料庫的 list 表格。OnlineUsersTableViewController.swift.
該 controller 使用 Firebase’s presence feature 展示所有當前線上 users。
此外,還有兩個模型類 GroceryItem.swift 和 User.swift 。它們做為 app 的資料模型。
Build and run, 你將看到如下這樣效果:
注: 當 build 工程時,我們將看到一些 ‘nullability’ 編譯警告。它們來自Firebase,暫時我們先忽略它們,稍後解決。
我們可以點選 Login 進行登入,這將使用一個寫死的 user 資料,現在該 app 還只能使用本地資料。接下來我們將呼叫 Firebase 資料使 app 生動起來。
建立 Firebase 賬號
有兩個重要步驟:
1. 建立免費 Firebase 賬號
2. 獲取你第一個 app 的 URL
我們可以訪問 Getting Started page 進行註冊。當我們使用我們谷歌賬號共享登入進入 firebase, 我們將看到一個乾淨的 Firebase 控制檯。不要擔心費用問題,現在 Firebase 免費版本已經足夠強大,夠用了。
建立我們的第一個工程,點選 CREATE NEW PROJECT 。在彈出的對話方塊中輸入專案名稱以及你的首選 國家/地區:
點選 CREATE PROJECT, 我們就可以通過控制皮膚來管理我們的專案了。
這將作為所有 Firebase 服務的容器,我們用它儲存資料和授權使用者。
選擇 Add Firebase to your iOS app 開始我們的專案。本專案的 bundle ID 是 rw.firebase.gettingstarted,所以新增此 id 到 iOS bundle ID 文字框。
點選 ADD APP ,將下載一個 GoogleService-Info.plist 檔案。將該檔案拖拽到 Xcode 中的 Grocr 專案。
點選 CONTINUE. 接下來一頁描述怎樣安裝 Firebase SDK。
本專案已經替我們整合好了,所以點選 CONTINUE 繼續。最後一頁說明當 app 啟動時怎樣連線到 Firebase。
點選 FINISH ,檢視新專案細節。
在 Xcode 開啟 GroceryListTableViewController.swift ,新增如下程式碼,建立 Firebase 連線。
let ref = FIRDatabase.database().reference(withPath: "grocery-items")
這個 Firebase 連線使用已提供的 path。在 documentation 中,這些 Firebase 屬性被稱為 references ,它們指定 Firebase 的位置。
簡言之,這些屬性可以實現儲存和同步資料到給定的位置。
我們發現,base URL 不是必須的,相反,它使用 grocery-items 的 child path。Firebase 資料庫是 JSON NoSQL 資料庫,所以資料都是儲存為 JSON 格式。
JSON 是分等級的 key-value 資料結構 – keys 指的是可以根據它獲取其它物件格式的 values 值。JSON data 是一個簡單的 key value 對兒樹形結構。
在 Firebase 中,key 是一個 URL,value是形如 number, string, boolean , object 的隨意的資料。
Structuring Data
無論客戶端是什麼資料格式,儲存到 Firebase 的是 JSON 格式。下面是一個 JSON 示例:
// The root of the tree
{ // grocery-items
"grocery-items": {
// grocery-items/milk
"milk": {
// grocery-items/milk/name
"name": "Milk",
// grocery-items/milk/addedByUser
"addedByUser": "David"
},
"pizza": {
"name": "Pizza",
"addedByUser": "Alice"
},
}
}
在上面的 JSON 中,你可以看到每對兒資料都是以鍵值對兒形式出現的。我們可以繼續遍歷樹並在更深的位置檢索資料。
在上面的例子中,我們可以通過路徑檢索所有的 grocery item。
grocery-items
如果你想獲取第一個 grocery item ,你可以通過以下路徑獲取:
grocery-items/milk
因為所有的 Firebase keys 對應paths,所以 key 的名字選擇很重要。
Understanding Firebase References
一個基本的原則是,Firebase 引用指向 Firebase 中資料儲存的位置。如果我們建立多引用,那麼這些引用共享同一個連線。
看如下程式碼:
// 1
let rootRef = FIRDatabase.database().reference()
// 2
let childRef = FIRDatabase.database().reference(withPath: "grocery-items")
// 3
let itemsRef = rootRef.child("grocery-items")
// 4
let milkRef = itemsRef.child("milk")
// 5
print(rootRef.key) // prints: ""
print(childRef.key) // prints: "grocery-items"
print(itemsRef.key) // prints: "grocery-items"
print(milkRef.key) // prints: "milk"
下面我們解釋下:
1. 我們建立一個到 Firebase 資料庫 root 引用。
2. 使用一個 URL ,我們可以建立一個引用到 Firebase 資料庫的子路徑。
3. 通過給 rootRef 傳遞子路徑,我們可以使用 child(_:) 建立子引用,這個引用和上面的引用是一樣意思。
4. 使用 itemsRef ,我們可以建立到 milk 的子引用。
5. 每個引用都有 key 屬性。這個屬性和 Firebase 資料庫關鍵字的名字一樣。
我們不需要在同一個專案中都新增這樣的程式碼,這裡只是出於展示目的進行列舉。
Adding New Items to the List
在 GroceryListTableViewController.swift 的底部,找到 addButtonDidTouch(_:) 方法。
在這裡我們要實現通過 UIAlertController 的方式新增一個新的 item 。
在 saveAction 方法內,現在僅僅儲存資料到一個本地 array,因此 saveAction 不能同步不同客戶端的資料,而且在下次啟動 app 時,儲存的資料將丟失。
沒有人會使用不能記錄或者同步他們 grocery 清單資料的 app ! 讓我們完善 saveAction 方法:
let saveAction = UIAlertAction(title: "Save",
style: .default) { _ in
// 1
guard let textField = alert.textFields?.first,
let text = textField.text else { return }
// 2
let groceryItem = GroceryItem(name: text,
addedByUser: self.user.email,
completed: false)
// 3
let groceryItemRef = self.ref.child(text.lowercased())
// 4
groceryItemRef.setValue(groceryItem.toAnyObject())
}
註釋如下:
1. 從 alert controller 獲取 text field 和它的內容。
使用當前使用者資料建立一個新的 GroceryItem 。
使用 child(_:) 建立一個子引用,這個引用的 key 是 item 的小寫名稱,因此如果我們新增一個複製的 item (即使使用大寫字母,或者使用混合字母),資料庫只儲存最後一個。
使用 setValue(_:) 儲存資料到資料庫。這個方法期望一個字典格式。GroceryItem 有個 toAnyObject() 方法,可以轉換物件為字典格式。
在你可以連線資料庫之前,我們還需要配置它。找到 AppDelegate.swift ,並在 application(_:didFinishLaunchingWithOptions:) 返回 true 之前新增如下程式碼:
FIRApp.configure()
預設情況,Firebase 資料庫需要使用者授權讀寫許可權。在瀏覽器進入 Firebase 控制皮膚,選中左邊的 Database 選項,設定 RULES 如下:
{
"rules": {
".read": true,
".write": true
}
}
修改後,選擇 PUBLISH 按鈕進行儲存設定。
Build and run. 在 Firebase 控制皮膚,選擇 DATA 標籤,並將瀏覽器視窗緊挨模擬器。當我們在模擬器中新增 item ,我們將看到它會出現在控制皮膚。
現在,我們就有了一個可以實時新增資料到 Firebase 的活生生的 grocery list app!但是雖然 key 特性已經可以執行完好了,但是沒有資料新增到table view。
那麼我們怎樣才能將資料從資料庫同步到 table view 呢?
Retrieving Data
我們可以通過 observeEventType(_:withBlock:) 方法非同步檢索 Firebase 中的資料。
在 GroceryListTableViewController.swift 的 viewDidLoad() 下新增如下方法:
ref.observe(.value, with: { snapshot in
print(snapshot.value)
})
該方法有兩個引數:FIRDataEventType 的一個例項以及一個閉包。
event type 確定我們要監聽的事件,.value 監聽諸如 add, removed, changed 這樣的 Firebase 資料庫重點資料改變。
當改變發生,資料庫使用最新資料更新 app 顯示。
app 在閉包方法中通過接受到的 FIRDataSnapshot 一個例項獲知資料改變。snapshot,代表某個特定時間點的資料快照。我們可以通過 value 那個屬性獲取到 snapshot 的資料。
Build and run,我們將看到,在控制檯會有 items 列表資料被列印出來。
Optional({
pizza = {
addedByUser = "hungry@person.food";
completed = 0;
name = Pizza;
};
})
Synchronizing Data to the Table View
注意列印日誌–現在在 table view 中可以看到 grocery 列表了。
在 GroceryListTableViewController.swift, 替換之前的程式碼片段為如下程式碼:
// 1
ref.observe(.value, with: { snapshot in
// 2
var newItems: [GroceryItem] = []
// 3
for item in snapshot.children {
// 4
let groceryItem = GroceryItem(snapshot: item as! FIRDataSnapshot)
newItems.append(groceryItem)
}
// 5
self.items = newItems
self.tableView.reloadData()
})
以上程式碼的諸行解釋:
新增一個監聽器監聽 grocery-items 改變了什麼。
儲存最近一次版本資料到閉包中本地的一個變數中。
監聽者閉包返回最近資料的一個 snapshot,這個 snapshot 包含所有的 grocery items,而不是僅僅包含改變的 items。使 snapshot.children ,我們可以迴圈獲取 grocery items 。
GroceryItem 結構有一個常用的例項化器,它使用 FIRDataSnapshot
來填充它的屬性。snapshot 的值可以為任意型別,可以是 dictionary, array, number, or string。當建立好一個 GroceryItem 例項,它被新增到一個包含最近一次版本資料的陣列中。將最新版本的資料賦值給 items,然後更新 table view,使它展示最新資料。
Build and run. 新增一個 pizza item 怎麼樣? 它將顯示到 table view。
Removing Items From the Table View
table view 將同步我們所有的改變資料, 但是當我們想刪除 pizza 時,現在還不能更新。
為了通知資料庫刪除資料,我們需要設定一個 Firebase reference,當使用者輕掃時候刪除 item。
定位到 tableView(_:commit:forRowAt:)。現在,該方法使用 index 移除 array 中的 grocery item。這可以實現功能,但我們還有更好的解決方法。替換為如下實現方式:
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let groceryItem = items[indexPath.row]
groceryItem.ref?.removeValue()
}
}
Firebase 遵從單向資料流模型,因此 viewDidLoad() 的 listener 監聽 grocery list 的最新資料。清除 item 觸發資料改變。
index path 的 row 被用來獲取相關的 grocery item。每個 GroceryItem 擁有一個名為 ref 的 Firebase reference property,呼叫 它的 removeValue() 將移除我們在 viewDidLoad() 定義的 listener。該listener有一個閉包,它使用最新的資料重新載入表檢視。
Build and run. 輕掃 item ,點選刪除,我們發現 app 和 Firebase 的資料都消失了。
Nice work! 我們 items 可以實時刪除了。
Checking Off Items
現在我們知道了怎麼新增、刪除以及同步 items ,這很酷。但是當我們實際購物時候會怎樣呢?我們會刪除我們剛購買的物品麼,或者當我們新增購物車時給物品打個標記是否更好?
在以前的紙質時代,人們過去常常把東西從購物清單上劃掉,因為我們也將在我們的 app 用現代的方式模仿這個行為。
開啟 GroceryListTableViewController.swift ,找到 toggleCellCheckbox(_:isCompleted:) 方法,該方法可以根據 item 是否完成來切換UITableViewCell 的必要檢視屬性。
當 table view 第一次載入後,剛方法在tableView (_:cellForRowAtIndexPath:) 中會被呼叫,以及當使用者點選 cell 時也會被呼叫。
替換 tableView(_:didSelectRowAt:) 方法為如下:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// 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:) 確定使用者點選的 cell。
2. 根據 index path 的 row 獲取對應的 GroceryItem。
3. 改變 grocery item 的 completed 的狀態。
4. 呼叫 toggleCellCheckbox(_:isCompleted:) 更新 cell 的屬性。
5. 在 updateChildValues(:) 方法中,通過傳遞字典引數,更新Firebase。該方法與 setValue(:) 不同,因為它只應用更新,而setValue(_:) 具有破壞性,並在該引用中替換整個值。
Build and run. 點選一個 item,我們就可以看到該行被勾號標記並排序。
恭喜,我們已經完成了一個相當漂亮的 grocery list app 。
Sorting the Grocery List
如果把 ice cream 放在未排序的標記裡面,有時我們可能會忘記它。現在讓我們進行些優化。
如果可以把已選中的 items 自動移動到列表底部,我們的 app 將更加令人喜歡。這樣,未被標記的 items 可以更容易被我們發現。
使用 Firebase queries, 我們可以根據任意屬性對列表進行排序,在GroceryListTableViewController.swift, 更新 viewDidLoad() 方法:
ref.queryOrdered(byChild: "completed").observe(.value, with: { snapshot in
var newItems: [GroceryItem] = []
for item in snapshot.children {
let groceryItem = GroceryItem(snapshot: item as! FIRDataSnapshot)
newItems.append(groceryItem)
}
self.items = newItems
self.tableView.reloadData()
})
通過關鍵詞 “ completed”,使用 Firebase 引用 queryOrdered(byChild:) 對資料進行排序。
由於列表需要完成順序,所以 completed 鍵將傳遞給查詢。然後,queryOrdered(byChild:)返回一個引用,通知伺服器以有序的方式返回資料。
Build and run. 點選一行,使其置換為已完成狀態,我們將看到,它神奇地自動移動到了最後一行。
哇! 我們現在真的讓購物變得更容易了。跨多個使用者同步資料,似乎應該足夠簡單,例如,與一個重要的其他使用者或 housemate。這聽起來像…身份驗證!
Authenticating Users
Firebase 有一個 authentication service,它允許 apps 驗證不同的提供者,我們可以使用 Google, Twitter, Facebook, Github, email & password, 匿名, 甚至 custom backends 這些方式。這裡我們使用郵箱和密碼方式進行身份認證,因為這種方式是最簡單的。
進入 Firebase dashboard ,點選 Auth,啟用郵箱密碼認證。
選中 SIGN-IN METHOD 標籤欄,再在 Sign-in providers 那一節選中Email/Password 行,切換 Enable 並點選 SAVE:
Firebase 儲存賬戶資訊到 keychain,因此最後一步,在專案中,切換到 target’s Capabilities 開啟 Keychain Sharing 開關。
現在,我們已經可以使用郵箱和密碼進行身份認證了。
Registering Users
在 LoginViewController.swift,找到 signUpDidTouch(_:) 方法,這裡會彈出 UIAlertController 讓使用者註冊賬號,定位到 saveAction 方法,新增以下程式碼到方法塊兒。
// 1
let emailField = alert.textFields![0]
let passwordField = alert.textFields![1]
// 2
FIRAuth.auth()!.createUser(withEmail: emailField.text!,
password: passwordField.text!) { user, error in
if error == nil {
// 3
FIRAuth.auth()!.signIn(withEmail: self.textFieldLoginEmail.text!,
password: self.textFieldLoginPassword.text!)
}
}
以上程式碼解釋:
1. 從彈框中獲取郵箱和密碼。
2. 呼叫 Firebase 方法 createUser(withEmail:password:),傳遞郵箱和密碼給它。
3. 如果執行沒有錯誤,使用者賬號即被建立。但是,我們還要再進行一下登入操作 signIn(withEmail:password:) ,同樣需要傳遞郵箱和密碼。
Build and run. 點選 Sign up ,鍵入郵箱和密碼,點選儲存。現在 view controller 還不能在登入成功後導航到其它地方。我們重新整理 Firebase Login & Auth ,我們將看到新建的使用者。
喔!我們的 app 現在可以讓使用者註冊並進行登入了,不過我們先不要慶祝,我們還需要再做些優化,好使使用者更好的使用它。
Logging Users In
Sign up 按鈕可以註冊和登入,然而 Login 現在還什麼都做不了,因為我們還沒有給它繫結驗證。
到 LoginViewController.swift, 找到 loginDidTouch(_:) 方法,修改如下:
@IBAction func loginDidTouch(_ sender: AnyObject) {
FIRAuth.auth()!.signIn(withEmail: textFieldLoginEmail.text!,
password: textFieldLoginPassword.text!)
}
當使用者點選 Login 時,這些程式碼將驗證使用者資訊。
我們接下來需要在使用者登入成功後導航到下一個頁面。
Observing Authentication State
Firebase 有可以監控使用者驗證狀態的觀察者。這裡是新增 segue 最好的地方。在 LoginViewController: 新增如下程式碼:
override func viewDidLoad() {
super.viewDidLoad()
// 1
FIRAuth.auth()!.addStateDidChangeListener() { auth, user in
// 2
if user != nil {
// 3
self.performSegue(withIdentifier: self.loginToList, sender: nil)
}
}
}
註釋如下:
1. 使用 addStateDidChangeListener(_:) 建立驗證觀察者。該 block 被傳入兩個引數:auth 和 user。
測試 user 的值,如果驗證通過,返回使用者資訊,如果驗證失敗,返回 nil 。
驗證成功,進行頁面跳轉。傳輸 sender 為 nil 。這看起來有些奇怪,但是稍後我們將在 GroceryListTableViewController.swift 進行設定。
Setting the User in the Grocery List
在 GroceryListTableViewController.swift 檔案 viewDidLoad(): 方法底部新增如下程式碼:
FIRAuth.auth()!.addStateDidChangeListener { auth, user in
guard let user = user else { return }
self.user = User(authData: user)
}
這裡我們新增了一個 Firebase auth object 的驗證觀察者,當使用者成功登入時,依次分配使用者屬性。
Build and run. 如果使用者已經登入,app 將跳過 LoginViewController 直接導航到 GroceryListTableViewController. 當使用者新增 items ,他們的 email 將顯示到 cell 的詳情裡面。
Success! app 現在已經有了基本的使用者驗證功能。
Monitoring Users’ Online Status
現在既然我們的 app 已經擁有了使用者驗證功能,那是時候新增監控哪個使用者線上功能了。開啟 GroceryListTableViewController.swift ,新增如下 property:
let usersRef = FIRDatabase.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 建立一個 child 引用,當 Firebase 建立一個賬號時,這個引用會被生成。
2. 使用這個引用儲存當前使用者的 email.
3. 當 Firebase 連線關閉的時候,例如使用者退出 app , 呼叫 currentUserRef 的 onDisconnectRemoveValue(),刪除位置引用的值。這可以完美監控離線使用者。
Build and run. 當 view 載入時,當前使用者的電子郵件,會被新增在當前線上位置的一個子節點。
Great! 現在當使用者數量增加時,是時候改變 bar button item 的個數了。
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 的 title 隨之更新。
Displaying a List of Online Users
開啟 OnlineUsersTableViewController.swift,在 class 的 property section 新增一個本地引用到 Firebase 的線上使用者記錄。
let usersRef = FIRDatabase.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. 建立一個 children added 監聽器,新增到被 usersRef 管理的位置。這與值偵聽器不同,因為只有新增的 child 被傳遞到閉包。
- 從 snapshot 獲取值,並賦值給本地變數 array。
- 因為 table view 的座標從 0 開始計算,當前的 row 總是等於 array 的個數 -1。
使用當前 row index 建立一個 NSIndexPath.
使用動畫從頂部新增一行到 table view.
這將只渲染新增的條目,而不是重新載入整個列表,而且還可以指定一個漂亮的動畫。:]
由於使用者可以離線,table 需要對被刪除的使用者做出反應。在我們剛剛新增的程式碼下面新增以下內容:
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 引用的子元素。它在本地陣列中搜尋電子郵件的值,以找到相應的子條目,一旦找到,它就從表中刪除相關的行。
Build and run.
在 Firebase 使用者儀表板上點選 Online ,當前使用者的電子郵件將出現在表格中。使用一些技巧,可以在網上新增一個使用者,一旦你做了,它就會顯示在列表中。在儀表板上單擊刪除按鈕,使用者就會從 table 中消失….
Booyah! 當使用者被新增和刪除的時候,table 隨之更新了。
Enabling Offline
雜貨店因不穩定的資料連線而臭名昭著。你會認為他們現在都有了Wi-Fi,但是沒有!
不過沒關係,我們只需設定資料庫離線工作。開啟 * AppDelegate*,在(_:didFinishLaunchingWithOptions:) 底部方法返回 true 之前,新增如下程式碼:
FIRDatabase.database().persistenceEnabled = true
是的,就是這樣! 就像我們的應用能夠離線執行一樣。當 app 重啟,一旦建立網路連線,離線更新也將作用於我們的 Firebase 資料庫。Oooh-ahhhh !
Where To Go From Here?
我們可以在這裡下載 Grocr-final完整專案。
注意:下載完後,我們仍需要新增自己的 GoogleService-Info.plist 和 設定允許Keychain sharing 。
在這個Firebase教程中,我們通過構建一個協作的購物清單 app 瞭解了Firebase的基礎知識,我們已經實現了將資料儲存到一個 Firebase 資料庫、實時同步資料、認證使用者、監視線上使用者狀態以及實現了離線支援。所有這些都是在沒有寫一行伺服器程式碼的情況下完成的! :]
如果你對 Firebase 感興趣,請檢視文件 documentation,以及 Firebase 提供的示例。
如果您對這個Firebase教程、Firebase或示例應用有任何意見或問題,請加入下面的論壇討論!
上海 虹橋V1
2017.09.06 19:02
相關文章
- 【DocFX文件翻譯】DocFX 入門 (Getting Started with DocFX)
- Pyplot tutorial,Pyplot官方教程自翻譯
- Beaglebone - Getting Started
- getting started with transformjsORMJS
- Windows HLK Getting StartedWindows
- lxml官方入門教程(The lxml.etree Tutorial)翻譯XML
- Hive Getting Started補充Hive
- 優雅地亂玩Redux: Getting StartedRedux
- 在 Android 上使用協程(二):Getting startedAndroid
- [Java 8 Tutorial翻譯系列]Java forEach詳解Java
- Core Text Tutorial for iOS : Making a Magazine App 翻譯iOSAPP
- Getting Started功能讓您快速熟悉如何接入HMS Core
- ZooKeeper 官方教程[翻譯]
- [翻譯]CMAKE官方教程
- iOS動畫程式設計-Layer動畫[ 2 ] Getting Started with Layer AnimationsiOS動畫程式設計
- Remote Diagnostic Agent (RDA) - Getting Started (Doc ID 314422.1)REM
- Remote Diagnostic Agent (RDA) 4 - Getting Started [ID 314422.1]REM
- 翻譯:TORN@DO's Cracking Tutorial for (4千字)
- Getting Started and Beyond|雲原生應用負載均衡選型指南負載
- Android Auto-Building Apps for Auto,Getting Started with AutoAndroidUIAPP
- Firebase 教程: iOS 實時聊天iOS
- NetworkX教程中文翻譯
- Getting Started with Server-Managed Recovery (SMR) and RMAN 8.0/8i_50875.1Server
- Electron教程翻譯2:安裝
- [Spring Cloud Tutorial翻譯系列]微服務-定義、原則、好處SpringCloud微服務
- Oracle 19c DBA's Guide(01): Getting Started with Database AdministrationOracleGUIIDEDatabase
- [譯]A Simple CSS Animation TutorialCSS
- D3入門教程翻譯
- Oracle10g / 11g - Getting Started with Recovery Manager (RMAN) [ID 360416.1]Oracle
- [翻譯]阮一峰webpack教程(Demo集合)Web
- [Spring Cloud Tutorial翻譯系列二]Spring Cloud Config Server與git整合SpringCloudServerGit
- 《React官方文件》之教程TutorialReact
- 百度翻譯app怎麼調整置語音速度? 百度翻譯設定翻譯速度的教程APP
- Flutter遊戲引擎Flame -- 教程翻譯和例子解析Flutter遊戲引擎
- 翻譯 Tim Rose 的kibana外掛教程ROS
- [翻譯] Flutter 中的動畫 - 簡易指南 - 教程Flutter動畫
- Deep Learning Tutorial (翻譯) 之使用邏輯迴歸分類手寫數字MNIST邏輯迴歸
- Android Firebase接入(序)--Firebase簡介以及Firebase官方Demo的使用Android