Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Firebaseの新しいデータベース

1,013 views

Published on

DevFest Shikoku 2017でLTしたスライドです

Published in: Software

Firebaseの新しいデータベース

  1. 1. Firebaseの 新しいデータベース 2017/11/18
 DevFest Shikoku 2017
  2. 2. About Me • Twitter、GitHub、Qiita、
 SlideShare、Speaker Deck: ➡ hironytic • At work: ➡ iOS (Objective-C)、
 ときどき Android (Java)、
 Windows UWP(C#) • At home: ➡ iOS (Swift) ひろん
 (一宮 浩教)
  3. 3. Firebase •Remote Config •App Indexing •Dynamic Links •Invites •AdWords •AdMob •Analytics Develop Grow Earn •Cloud Messaging •Authentication •Realtime Database •Cloud Firestore (beta) •Storage •Hosting •Test Lab •Crash Reporting Oct.4, 2017
  4. 4. 機能の比較 • リアルタイム • オフライン • サーバーレス
 • 複数DBプラン有り • 柔軟なデータ構造 • 表現力の高いクエリ • スケール可能な設計 RTDB CFS RTDB CFS = Realtime Database = Cloud Firestore RTDB CFS RTDB CFS RTDB CFS CFS CFS https://firebase.google.com/docs/database/#key_capabilities https://firebase.google.com/docs/firestore/#key_capabilities
  5. 5. 機能の比較 • リアルタイム • オフライン • サーバーレス
 • 複数DBプラン有り • 柔軟なデータ構造 • 表現力の高いクエリ • スケール可能な設計 RTDB CFS RTDB CFS = Realtime Database = Cloud Firestore RTDB CFS RTDB CFS RTDB CFS CFS CFS https://firebase.google.com/docs/database/#key_capabilities https://firebase.google.com/docs/firestore/#key_capabilities
  6. 6. データ構造 Realtime Database
  7. 7. JSON Realtime Database { "users": { "nvGvwR5": { "name": "Nobita", "skill": "Hirune" }, "zzD7UAv": { "name": "Suneo", "skill": "Jiman" } } } Firebaseコンソールの表示
  8. 8. JSON Realtime Database { "users": { "nvGvwR5": { "name": "Nobita", "skill": "Hirune" }, "zzD7UAv": { "name": "Suneo", "skill": "Jiman" } } } データの取得イメージ /users/nvGvwR5/name ➡ "Nobita" /users/nvGvwR5 ➡ { 
 "name": "Nobita",
 "skill": "Hirune"
 } ,
  9. 9. • 指定した位置以下の子孫がすべて取得される Realtime Database 注意点 { "channels": { "-CSP36ah": { "name": "general", "messages": { "-MV5ahcO": {"from": "AAd7UZv", "message": "何してますか?忙しいですか..."}, "-MV5yaC0": {"from": "nvGvwR5", "message": "昼寝してた"}, "-MV6Almn": {"from": "AAd7UZv", "message": "近くのコンビニエンスストアで..."}, "-MV6L38V": {"from": "nvGvwR5", "message": "まかせといてよ"}, ... } }, "-CSP4CQz": { "name": "random", "messages": { ... } }, "-CSP4mAr": { "name": "oops", "messages": { ... } }, ... } } 😇「チャンネル一覧を取 得しようとしたら、チャ ンネル内のメッセージも 含めてすべてを取得し ちゃった☆」
  10. 10. • なるべくデータのネストを避ける工夫が必要 • アプリの挙動を考慮に入れて設計 Realtime Database 注意点 { "channels": { "-CSP36ah": { "name": "general" }, "-CSP4CQz": { "name": "random" }, "-CSP4mAr": { "name": "oops" }, ... }, "messages": { "-CSP36ah": { "-MV5ahcO": {"from": "AAd7UZv", "message": "何してますか?忙しいですか..."}, "-MV5yaC0": {"from": "nvGvwR5", "message": "昼寝してた"}, "-MV6Almn": {"from": "AAd7UZv", "message": "近くのコンビニエンスストアで..."}, "-MV6L38V": {"from": "nvGvwR5", "message": "まかせといてよ"}, ... }, "-CSP4CQz": { ... }, "-CSP4mAr": { ... }, ... } }
  11. 11. データ構造 Cloud Firestore
  12. 12. ドキュメント • JSONライクなKey-Value • Mapを使って構造化した
 ドキュメントも作れる Cloud Firestore { "name": "Nobita", "skill": "Hirune" }
  13. 13. コレクション • ドキュメントを含むコン テナ • ドキュメントはコレクショ ン内でユニークなIDを付 けて管理される Cloud Firestore { "name": "Nobita", "skill": "Hirune" } nvGvwR5 { "name": "Suneo", "skill": "Jiman" } zzD7UAv users
  14. 14. コレクション データの取得イメージ collection("users") ➡ nvGvwR5
 { 
 "name": "Nobita",
 "skill": "Hirune"
 } ,
 zzD7UAv
 { 
 "name": "Suneo",
 "skill": "Jiman"
 } , Cloud Firestore { "name": "Nobita", "skill": "Hirune" } nvGvwR5 { "name": "Suneo", "skill": "Jiman" } zzD7UAv users
  15. 15. サブコレクション { "name": "general" } CSP36ah { "name": "random" } CSP4CQz channels messages { "from": "AAd7UZv", "message": "何してますか?忙しいですか..." } MV5ahcO { "from": "nvGvwR5", "message": "昼寝してた" } MV5yaC0 { "from": "AAd7UZv", "message": "近くのコンビニエンスストアで..." } MV6Almn { "from": "nvGvwR5", "message": "まかせといてよ" } MV6L38V messages ... Cloud Firestore
  16. 16. サブコレクション { "name": "general" } CSP36ah channels messages { "from": "AAd7UZv", "message": "何してますか?忙しいですか..." } MV5ahcO { "from": "nvGvwR5", "message": "昼寝してた" } MV5yaC0 { "from": "AAd7UZv", "message": "近くのコンビニエンスストアで..." } MV6Almn { "from": "nvGvwR5", "message": "まかせといてよ" } MV6L38V collection("channels").document("CSP36ah").collection("messages") Cloud Firestore
  17. 17. クエリ Realtime Database
  18. 18. サンプルデータ • "shiitake":
 生しいたけの生産量(トン) • "konamon":
 人口10万人あたりのお好み焼き・ 焼きそば・たこ焼き店の事業所数 Realtime Database "shiitake":
 「平成28年特用林産物生産統計調査」(農林水産省) (http://www.maff.go.jp/j/tokei/kouhyou/ tokuyo_rinsan/) "konamon":
 「人口推計」(総務省統計局)(http://www.e-stat.go.jp/SG1/estat/ List.do?bid=000001039703&cycode=0)より「都道府県別人口」の平成26年、
 「平成26年経済センサス‐基礎調査結果」(総務省統計局)(http://www.e-stat.go.jp/SG1/ estat/List.do?bid=000001064598&cycode=0)より「産業(小分類)、経営組織(5区分)別全事 業所数、男女別従業者数及び1事業所当たり従業者数-全国、都道府県」
 から算出
  19. 19. ソート Realtime Database Database.database().reference(withPath: "pref") .queryOrdered(byChild: "shiitake") .observe(.childAdded) { snapshot in // ... } しいたけは、どこが多く生産してる?
 "shiitake"の値でソートしてみよう! <結果> 沖縄 | 26.1 佐賀 | 101.8 大阪 | 107.4 山梨 | 156.8 京都 | 167.6 東京 | 202.3 福井 | 213.8 山口 | 220.1 鳥取 | 232.1 青森 | 239.9 ... Database.database().reference(withPath: "pref") .queryOrdered(byChild: "shiitake") .observeSingleEvent(of: .value) { snapshot in // ... } ……これ、昇順じゃね? →降順ソートはできない 😩
  20. 20. 結果の数でフィルタRealtime Database Database.database().reference(withPath: "pref") .queryOrdered(byChild: "shiitake") .queryLimited(toLast: 5) .observeSingleEvent(of: .value) { snapshot in // ... } 気をとりなおして上位5件だけ取得
 (昇順なのでラスト5件) <結果> 群馬 | 3990.8 秋田 | 4223.6 岩手 | 4826.6 北海道 | 7613.5 徳島 | 8289.0 🙂
  21. 21. 値でフィルタ Realtime Database Database.database().reference(withPath: "pref") .queryOrdered(byChild: "chiho") .queryEqual(toValue: "近畿") .observeSingleEvent(of: .value) { snapshot in // ... } 近畿地方のデータを検索 <結果> 三重 | 676.4 滋賀 | 430.4 京都 | 167.6 大阪 | 107.4 兵庫 | 1342.3 奈良 | 417.7 和歌山 | 966.7
  22. 22. フィルタしてソートRealtime Database Database.database().reference(withPath: "pref") .queryOrdered(byChild: "chiho") .queryEqual(toValue: "近畿") .queryOrdered(byChild: "shiitake") .observeSingleEvent(of: .value) { snapshot in // ... } 近畿地方でしいたけ生産量の順にソート *** Terminating app due to uncaught exception 'InvalidQueryParameter', reason: 'Cannot use multiple queryOrderedBy calls!' 😢
  23. 23. クエリ Cloud Firestore
  24. 24. ソート 降順ソートが可能! 😀 Cloud Firestore <結果> 徳島 | 8289.0 北海道 | 7613.5 岩手 | 4826.6 秋田 | 4223.6 群馬 | 3990.8 長崎 | 3432.6 栃木 | 2451.1 福島 | 2444.4 新潟 | 2437.7 宮崎 | 2384.5 ... Firestore.firestore().collection("pref") .order(by: "shiitake", descending: true) .getDocuments { snapshot, error in // ... }
  25. 25. 結果の数でフィルタ Firestore.firestore().collection("pref") .order(by: "shiitake", descending: true) .limit(to: 5) .getDocuments { snapshot, error in // ... } 上位5件だけ取得 <結果> 徳島 | 8289.0 北海道 | 7613.5 岩手 | 4826.6 秋田 | 4223.6 群馬 | 3990.8 Cloud Firestore
  26. 26. 値でフィルタ Firestore.firestore().collection("pref") .whereField("chiho", isEqualTo: "近畿") .getDocuments { snapshot, error in // ... } 近畿地方のデータを検索 <結果> 三重 | 676.4 滋賀 | 430.4 京都 | 167.6 大阪 | 107.4 兵庫 | 1342.3 奈良 | 417.7 和歌山 | 966.7 Cloud Firestore
  27. 27. フィルタしてソート Firestore.firestore().collection("pref") .whereField("chiho", isEqualTo: "近畿") .order(by: "shiitake", descending: true) .getDocuments { snapshot, error in // ... } 近畿地方でしいたけ生産量の順にソート Cloud Firestore Error Domain=FIRFirestoreErrorDomain Code=9
 "The query requires an index. You can create it here: https:// console.firebase.google.com/project/……(以下略)" 😮 URL
  28. 28. フィルタしてソート Firestore.firestore().collection("pref") .whereField("chiho", isEqualTo: "近畿") .order(by: "shiitake", descending: true) .getDocuments { snapshot, error in // ... } 近畿地方でしいたけ生産量の順にソート Cloud Firestore Error Domain=FIRFirestoreErrorDomain Code=9
 "The query requires an index. You can create it here: https:// console.firebase.google.com/project/……(以下略)" 😮 URL
  29. 29. フィルタしてソート Firestore.firestore().collection("pref") .whereField("chiho", isEqualTo: "近畿") .order(by: "shiitake", descending: true) .getDocuments { snapshot, error in // ... } 近畿地方でしいたけ生産量の順にソート Cloud Firestore <結果> 兵庫 | 1342.3 和歌山 | 966.7 三重 | 676.4 滋賀 | 430.4 奈良 | 417.7 京都 | 167.6 大阪 | 107.4
  30. 30. 複数のフィールドでソート Firestore.firestore().collection("pref") .order(by: "chiho", descending: false) .order(by: "konamon", descending: true) .getDocuments { snapshot, error in // ... } 地方でソートし、その中は、
 人口あたりの粉もん屋の数でソート Cloud Firestore <結果> ... 四国 | 徳島 | 29.9354838709677 四国 | 高知 | 27.9627163781625 四国 | 愛媛 | 21.4134275618375 四国 | 香川 | 17.896865520728 東北 | 青森 | 3.55555555555556 東北 | 福島 | 2.96371997956055 東北 | 宮城 | 2.91970802919708 東北 | 秋田 | 2.91627469426152 東北 | 山形 | 2.68863833477884 東北 | 岩手 | 2.60336906584992 近畿 | 兵庫 | 34.9237668161435 近畿 | 大阪 | 32.1634127073694 近畿 | 京都 | 23.1735159817352 近畿 | 和歌山 | 21.3562753036437 近畿 | 奈良 | 18.6599423631124 近畿 | 三重 | 14.7202607278653 近畿 | 滋賀 | 11.032531824611
 ...
  31. 31. まとめ(ぼくの理解) データベース
 …というよりは、
 巨大なJSONストレージ
 ストアと名前がついて いるが、NoSQLの
 本格的なデータベース ご清聴ありがとうございました Realtime Database Cloud Firestore

×