[Swift版] 今さら聞けないFirebase④ Realtime Database

# はじめに
今さら聞けないFirebaseシリーズ第四弾は、Realtime Databaseの実装方法についてご紹介します。

## Realtime Databaseができること
・ストレージ上でデータを管理できる(JSON Tree)
・リアルタイムにデータを更新できる（数ミリ秒程度）
・オフラインでも利用できる

## ご説明する例
今回は、タイトルと完了済みフラグを管理する例でご説明します

```:ToDo.swift
import Foundation

class ToDo: NSObject {
    var title = ""
    var isDone = false
    
    init(title: String, isDone: Bool) {
        self.title = title
        self.isDone = isDone
    }
}
```

ストレージ上では、下記のように管理される想定です。
(FirebaseのDatabaseは、一つの大きなJSON Treeで管理されるようです)

<img width="379" alt="スクリーンショット 2016-08-06 10.45.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/71694/c8757a63-4467-a359-718f-40572b2027f1.png">

| キー名 | 説明 | 補足 |
|---|---|---|
| realtimedatabase-d0734 | データベース名 | 自動で割り当てられる |
| user-todolist | テーブル名 | |
| 7y5Cqzcnj7Ztrn408qLPqvuqWlp1| ユーザID | FIRAuth.auth()?.currentUser?.uid |
| KOSR7Jx7RknVe3LAxyT| 主キー | 自動で割り当てられる|
| title| 今回登録するデータ | 文字列 |
| isDone| 今回登録するデータ | Bool |

## やること
・Realtime Databaseの導入方法について
・データ登録、データ読み出しのサンプルコードのご紹介

## やらないこと
・[Firebaseの導入について]((http://qiita.com/eKushida/items/54b62d3961a5c74a71af))
・[会員登録、ログインについて](http://qiita.com/eKushida/items/5fe8fff256f8870f5be7)

# いざ、チャレンジ！

## 1. 導入方法

### 1.1. Podfileにモジュールを追加
なお、Authはユーザごとにデータを管理するために利用する

```:Podfile
    pod 'Firebase'
    pod 'Firebase/Auth'
    pod 'Firebase/Database'
```

## 2. 実装 
### 2.1. Firebaseモジュールのインポート
Realtime Databaseを使うクラスでimportしておく

```
import Firebase
import FirebaseDatabase
```

### 2.2. データ登録
データ登録は、保存したい階層までスラッシュで区切って指定する
なお、userIDはログイン時に取得したuidを指定する

```:ViewController.swift
    private func addToDoItem(userID: String, todo: ToDo) {
        
        let ref = FIRDatabase.database().reference()
        let key = ref.child("todolist").childByAutoId().key
        let childUpdates = ["/user-todolist/\(userID)/\(key)/": ["title": todo.title, "isDone" : todo.isDone]]
        
        ref.updateChildValues(childUpdates)
    }

```

### 2.3. データ読み出し
データ読み出しは、非同期で取得されるため、デリゲートを定義しておく

```:ViewController.swift
protocol ToDoImtesInput {
    func success(todoItems: [ToDo])
    func failure(error: NSError)
}
```

ユーザIDごとのデータを読み出し、読み出し完了後デリゲードで通知する

```:ViewController.swift
    private func loadTodoItems(userID: String){
        
        let ref = FIRDatabase.database().reference()
        ref.child("user-todolist").child(userID).observeSingleEventOfType(.Value, withBlock: {[weak self] (snapshot) in
            
            guard let weakSelf = self else  { return }
            
            var todoItems = [ToDo]()
            
            for item in snapshot.children {
                let child = item as! FIRDataSnapshot
                let dic = child.value as! NSDictionary
                
                todoItems.append(ToDo(title: dic["title"] as! String, isDone: dic["isDone"] as! Bool))
            }
            weakSelf.success(todoItems)
            
        }) {[weak self] (error) in
            guard let weakSelf = self else  { return }
            weakSelf.failure(error)
        }
    }
```

読み出したデータを表示する

```:ViewController.swift
extension ViewController: ToDoImtesInput {
    
    func success(todoItems: [ToDo]) {
        
        for todoItem in todoItems {
            print(todoItem.title, todoItem.isDone)
        }
    }
    
    func failure(error: NSError) {
        print(error.description)
    }
}
```

# まとめ
今回は、Realtime Databaseの実装方法について、ご紹介しました。
ストレージで管理するデータは、他にもルール設定ができ、アクセス制限等ができるようです。

今後は複数テーブルの例も纏めてみたいと思います。