美文网首页iOS DeveloperiOS开发
Firebase Tutorial: Getting Start

Firebase Tutorial: Getting Start

作者: _浅墨_ | 来源:发表于2017-09-06 19:02 被阅读1007次

    备注: 本教程已由 Attila Hegedüs 更新适配 iOS 10 和 Swift 3,原教程由David East 创作。
    原文:https://www.raywenderlich.com/139322/firebase-tutorial-getting-started-2
    翻译:JoeyChang 转载请标明出处

    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,稍后我们将优化它。

    2. GroceryListTableViewController.swift.
      这个 controller 是 UITableViewController 子类,它通过 UIAlertController 添加 items 到本地数据库的 list 表格。

    3. OnlineUsersTableViewController.swift.
      该 controller 使用 Firebase’s presence feature 展示所有当前在线 users。

    此外,还有两个模型类 GroceryItem.swiftUser.swift 。它们做为 app 的数据模型。

    Build and run, 你将看到如下这样效果:

    Grocr-Starter

    注: 当 build 工程时,我们将看到一些 ‘nullability’ 编译警告。它们来自Firebase,暂时我们先忽略它们,稍后解决。

    我们可以点击 Login 进行登录,这将使用一个写死的 user 数据,现在该 app 还只能使用本地数据。接下来我们将调用 Firebase 数据使 app 生动起来。

    创建 Firebase 账号

    有两个重要步骤:

    1. 创建免费 Firebase 账号
    2. 获取你第一个 app 的 URL

    我们可以访问 Getting Started page 进行注册。当我们使用我们谷歌账号共享登录进入 firebase, 我们将看到一个干净的 Firebase 控制台。不要担心费用问题,现在 Firebase 免费版本已经足够强大,够用了。

    01-firebase-welcome
    创建我们的第一个工程,点击 CREATE NEW PROJECT 。在弹出的对话框中输入项目名称以及你的首选 国家/地区:

    02-firebase-create-project

    点击 CREATE PROJECT, 我们就可以通过控制面板来管理我们的项目了。

    03-firebase-dashboard

    这将作为所有 Firebase 服务的容器,我们用它存储数据和授权用户。
    选择 Add Firebase to your iOS app 开始我们的项目。本项目的 bundle ID 是 rw.firebase.gettingstarted,所以添加此 id 到 iOS bundle ID 文本框。

    04-firebase-add-ios-app-1

    点击 ADD APP ,将下载一个 GoogleService-Info.plist 文件。将该文件拖拽到 Xcode 中的 Grocr 项目。

    04-firebase-add-ios-app-2

    点击 CONTINUE. 接下来一页描述怎样安装 Firebase SDK。

    04-firebase-add-ios-app-3

    本项目已经替我们集成好了,所以点击 CONTINUE 继续。最后一页说明当 app 启动时怎样连接到 Firebase。

    04-firebase-add-ios-app-4

    点击 FINISH ,查看新项目细节。

    04-firebase-add-ios-app-5

    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 和它的内容。

    2. 使用当前用户数据创建一个新的 GroceryItem 。

    3. 使用 child(_:) 创建一个子引用,这个引用的 key 是 item 的小写名称,因此如果我们添加一个复制的 item (即使使用大写字母,或者使用混合字母),数据库只保存最后一个。

    4. 使用 setValue(_:) 保存数据到数据库。这个方法期望一个字典格式。GroceryItem 有个 toAnyObject() 方法,可以转换对象为字典格式。

    在你可以连接数据库之前,我们还需要配置它。找到 AppDelegate.swift ,并在 application(_:didFinishLaunchingWithOptions:) 返回 true 之前添加如下代码:

    FIRApp.configure()
    

    默认情况,Firebase 数据库需要用户授权读写权限。在浏览器进入 Firebase 控制面板,选中左边的 Database 选项,设置 RULES 如下:

    firebase-db-rules
    {
      "rules": {
        ".read": true,
        ".write": true
      }
    }
    

    修改后,选择 PUBLISH 按钮进行保存设置。
    Build and run. 在 Firebase 控制面板,选择 DATA 标签,并将浏览器窗口紧挨模拟器。当我们在模拟器中添加 item ,我们将看到它会出现在控制面板。

    fb-save

    现在,我们就有了一个可以实时添加数据到 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()
    })
    

    以上代码的诸行解释:

    1. 添加一个监听器监听 grocery-items 改变了什么。

    2. 存储最近一次版本数据到闭包中本地的一个变量中。

    3. 监听者闭包返回最近数据的一个 snapshot,这个 snapshot 包含所有的 grocery items,而不是仅仅包含改变的 items。使 snapshot.children ,我们可以循环获取 grocery items 。

    4. GroceryItem 结构有一个常用的实例化器,它使用 FIRDataSnapshot
      来填充它的属性。snapshot 的值可以为任意类型,可以是 dictionary, array, number, or string。当创建好一个 GroceryItem 实例,它被添加到一个包含最近一次版本数据的数组中。

    5. 将最新版本的数据赋值给 items,然后更新 table view,使它展示最新数据。
      Build and run. 添加一个 pizza item 怎么样? 它将显示到 table view。

    fb-sync
    不用刷新,就可以及时获取到更新后的数据。

    realtime-updates

    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 的数据都消失了。

    fb-delete

    Nice work! 我们 items 可以实时删除了。

    Checking Off Items

    现在我们知道了怎么添加、删除以及同步 items ,这很酷。但是当我们实际购物时候会怎样呢?我们会删除我们刚购买的物品么,或者当我们添加购物车时给物品打个标记是否更好?

    在以前的纸质时代,人们过去常常把东西从购物清单上划掉,因为我们也将在我们的 app 用现代的方式模仿这个行为。

    grocery-list

    打开 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,我们就可以看到该行被勾号标记并排序。

    fb-toggle
    恭喜,我们已经完成了一个相当漂亮的 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. 点击一行,使其置换为已完成状态,我们将看到,它神奇地自动移动到了最后一行。

    fb-order

    哇! 我们现在真的让购物变得更容易了。跨多个用户同步数据,似乎应该足够简单,例如,与一个重要的其他用户或 housemate。这听起来像…身份验证!

    Authenticating Users

    Firebase 有一个 authentication service,它允许 apps 验证不同的提供者,我们可以使用 Google, Twitter, Facebook, Github, email & password, 匿名, 甚至 custom backends 这些方式。这里我们使用邮箱和密码方式进行身份认证,因为这种方式是最简单的。

    进入 Firebase dashboard ,点击 Auth,激活邮箱密码认证。

    fb-auth-1

    选中 SIGN-IN METHOD 标签栏,再在 Sign-in providers 那一节选中Email/Password 行,切换 Enable 并点击 SAVE:

    authentication

    Firebase 存储账户信息到 keychain,因此最后一步,在项目中,切换到 target’s Capabilities 打开 Keychain Sharing 开关。

    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 ,我们将看到新建的用户。

    fb-register-user

    喔!我们的 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。

    2. 测试 user 的值,如果验证通过,返回用户信息,如果验证失败,返回 nil 。

    3. 验证成功,进行页面跳转。传输 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 的详情里面。

    fb-user-add

    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 加载时,当前用户的电子邮件,会被添加在当前在线位置的一个子节点。

    fb-monitoring

    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 被传递到闭包。

    2. 从 snapshot 获取值,并赋值给本地变量 array。

    3. 因为 table view 的坐标从 0 开始计算,当前的 row 总是等于 array 的个数 -1。

    4. 使用当前 row index 创建一个 NSIndexPath.

    5. 使用动画从顶部添加一行到 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 中消失….

    fb-users-table

    Booyah! 当用户被添加和删除的时候,table 随之更新了。

    monintoring-users
    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

    相关文章

      网友评论

        本文标题:Firebase Tutorial: Getting Start

        本文链接:https://www.haomeiwen.com/subject/jjkwrxtx.html