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で驚くほど簡単に作れるリアルタイムイベントドリブンアプリ

6,516 views

Published on

Firebaseで驚くほど簡単に作れるリアルタイムイベントドリブンアプリ

Published in: Technology
  • Be the first to comment

Firebaseで驚くほど簡単に作れるリアルタイムイベントドリブンアプリ

  1. 1. Firebaseで驚くほど簡単に作れる リアルタイムイベントドリブンアプリ 2015-09-29 @Roppongi.aar #1
  2. 2. 自己紹介 • 白山 文彦 • 株式会社マナボ 技術者 • @fushiroyama
  3. 3. Firebaseとは
  4. 4. • REALTIME DATABASE • AUTHENTICATION • HOSTING • @see https://www.firebase.com/
  5. 5. 今日扱うのは REALTIME DATABASE
  6. 6. REALTIME DATABASE • NoSQL • Data is stored as JSON • Realtime Data Synchronization • Mobile Offline Support
  7. 7. • アプリからはJSONツリーの任意の部分木を参照する • 参照した部分へ任意のデータを追加すると即座にバッ クエンドでDBの内容が同期される • 参照している部分へ誰かがデータを追加したり更新し たりといったイベントをほぼリアルタイムに受け取る ことができる • 同時並行編集も安全に行える • オフライン状態でも追加・更新できる(詳しくは後述)
  8. 8. • 部分木ごとに細やかなアクセス制限が可能 • ここはReadだけ、ここはRead/Write、ここは 認証済みユーザのみ、等もお手の物 • Facebook, Twitter, GitHub, Google の認証機能 がクライアントサイドの開発だけで利用可能 • カスタム認証(つまりすでに持ってる自前のサー ビスのユーザ認証)とも連携可能
  9. 9. 分かりやすいので いきなりデモ
  10. 10. デモ
  11. 11. Quickstart
  12. 12. build.gradle dependencies { compile 'com.firebase:firebase-client-android:2.4.0+' }
  13. 13. build.gradle android { ... packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/LICENSE-FIREBASE.txt' exclude 'META-INF/NOTICE' } }
  14. 14. AndroidManifest.xml <uses-permission android:name="android.permission.INTERNET" />
  15. 15. CustomApplication @Override public void onCreate() { super.onCreate(); Firebase.setAndroidContext(this); // other setup code }
  16. 16. Activity Firebase myFirebaseRef = new Firebase("https://<YOUR-FIREBASE- APP>.firebaseio.com/"); Create Reference
  17. 17. Writing Data myFirebaseRef.child("message") .setValue("Do you have data? You'll love Firebase."); Child Node key write!
  18. 18. Reading Data myFirebaseRef.child("message").addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { //prints "Do you have data? You'll love Firebase." System.out.println(snapshot.getValue()); } @Override public void onCancelled(FirebaseError error) { } }); Child Node key read!
  19. 19. 有効なデータ型 • String • Boolean • Long • Double • Map<String, Object> • List<Object> • およびこれらの再帰的なデータ構造
  20. 20. Arrayに注意 • 純粋なArrayは提供されない。 • ["hoge", "fuga"]は内部的に{0: "hoge", 1: "fuga"} • 理由は並行操作を安全に行うため(添字は要素の削 除で振り直される) • https://www.firebase.com/docs/android/ guide/understanding-data.html
  21. 21. 色々な保存方法 • setValue() • updateChildren() • push() • runTransaction()
  22. 22. setValue • 一番基本的な保存方法。対応するパス/キーの値を そのままupsert(子ノードも含めて全部書き換わ る) • POJOはアノテーションとかなくてもちゃんとオブ ジェクトとして保存できる。
  23. 23. updateChildren • 一部の更新に使う • 例えばHashにたいしてsetValue()してしまうと全 てが書き換わるので、一部のkey/valueだけ更新し たいときとかに使う
  24. 24. Firebase alanRef = usersRef.child("alanisawesome"); Map<String, Object> nickname = new HashMap<String, Object>(); nickname.put("nickname", "Awesome Alan"); alanRef.updateChildren(nickname); 色んなユーザが入ったツリー
  25. 25. push • 同一エンドポイントに同時に書き込みがあるような 場合に重複が起こると古いほうが消されちゃうので push() を挟んでやると一意なキーを発行してくれ る。 • キーはタイムスタンプを元に作られているので時系 列でソートされる。
  26. 26. Firebase postRef = ref.child("posts"); Map<String, String> post1 = new HashMap<String, String>(); post1.put("author", "gracehop"); post1.put("title", "Announcing COBOL, a New Programming Language"); postRef.push().setValue(post1); Map<String, String> post2 = new HashMap<String, String>(); post2.put("author", "alanisawesome"); post2.put("title", "The Turing Machine"); postRef.push().setValue(post2);
  27. 27. runTransaction • 時間がないので今日は省略。資料 • https://www.firebase.com/docs/android/ guide/saving-data.html
  28. 28. 色々な読み出し方法 • addValueEventListener • addChildEventListener • onChildAdded • onChildChanged • onChildDeleted • onChildMoved
  29. 29. addValueEventListener • 一番シンプルな取得方法 • 指定したキー以下を全部取得
  30. 30. Firebase ref = new Firebase("https://docs-examples.firebaseio.com/web/saving-data/fireblog/posts"); // Attach an listener to read the data at our posts reference ref.addValueEventListener(new ValueEventListener() {     @Override     public void onDataChange(DataSnapshot snapshot) {         System.out.println(snapshot.getValue());     }     @Override     public void onCancelled(FirebaseError firebaseError) {         System.out.println("The read failed: " + firebaseError.getMessage());     } }); getValue(Class<T> clazz) だと型安全
  31. 31. addChildEventListener
  32. 32. onChildAdded • リストを参照しているときに子ノードが追加される と呼ばれる • 追加されたノードがコールバックされる • snapShot.getKey()でそのキーを取れるので両方合 わせてAndroidアプリローカルにHashMapで持っ ておいてListViewのAdapterで利用するとかはよく あるかも。
  33. 33. Firebase ref = new Firebase("https://docs-examples.firebaseio.com/web/saving-data/fireblog/posts"); ref.addChildEventListener(new ChildEventListener() { // Retrieve new posts as they are added to the database @Override public void onChildAdded(DataSnapshot snapshot, String previousChildKey) { BlogPost newPost = snapshot.getValue(BlogPost.class); System.out.println("Author: " + newPost.getAuthor()); System.out.println("Title: " + newPost.getTitle()); } //... ChildEventListener also defines onChildChanged, onChildRemoved, // onChildMoved and onCanceled, covered in later sections. });
  34. 34. onChildChanged • onChildChangedはデータパス以下のノードが変 更されたときにコールバックされる。子ノードのど んな子孫に対するいかなる変更でも通知される。 • onChildAddedやonChildRemovedと組み合わせ てよく使われる。 • コールバックには変更のあったノードの情報がスナッ プショットとして渡される。
  35. 35. onChildDeleted • 削除されたときにコールバックされてくる。あとは さっきのと同じ。 • コールバックに渡されるスナップショットは削除さ れたノード。
  36. 36. onChildMoved • ノードの移動で発火される。あとはさっきのとry
  37. 37. イベントに関する保証 • ローカルの状態変更でもこれらのイベントはトリガされる • イベントは最終的には常にデータの正しい状態を反映する。つ まり、ネットワークの瞬断などでローカルの操作やタイミング が一時的にローカルデータとの差異を生んだとしても。 • ある1人のユーザからの書き込みは常にサーバに書き込まれ、そ の後他人にブロードキャストされるという順番が守られる。 • ValueEventは常に最後にトリガされ、それより前に起こったい かなるイベントからの差分も含まれていることが保証されてい る。
  38. 38. その他TIPS • リスナの解除には ref.removeEventListener(originalListener); を呼ぶ。 • 複数のリスナを登録している場合にはその分だけ全部解除を呼ん でやる必要がある(めんどくさい・・・) • 親ノードへのリスナ登録、そしてそれを解除したからといって更 に下位のノードへのリスナが自動で解除されるわけではない。全 部登録した数だけ手動で解除する必要がある。 • 初回だけ実行されてあとは何もしないのが都合がいいリスナがあ る場合は addListenerForSingleValueEvent を使うと便利だよ。
  39. 39. まとめ • オフライン機能とリアルタイム同期があるので、今まで 困っていたSocket.IO(WebSocket)などのオフライン - > オンライン復帰時の再送みたいな処理を、複雑なコー ドを一切書かずに実現できるのが素晴らし過ぎる。 • 並行操作の制約上、純粋な配列がサポートされていな いとか、NoSQLなのでJOINが使えないとか、性質を理 解して使わないといけない部分もある。 • ちゃんと使うなら意外に高額になる?
  40. 40. まとめ • それでもなお余りある魅力! • 是非一度評価してみてください!驚きます!
  41. 41. 素晴らしきサンプルたち • https://www.firebase.com/docs/android/ examples.html • https://github.com/firebase/AndroidChat • https://github.com/firebase/AndroidDrawing
  42. 42. 公式リファレンスショートカット • Quickstart • https://www.firebase.com/docs/android/quickstart.html • データ構造の理解 • https://www.firebase.com/docs/android/guide/understanding-data.html • データ保存 • https://www.firebase.com/docs/android/guide/saving-data.html • データ取得 • https://www.firebase.com/docs/android/guide/retrieving-data.html • 効率的なデータ構造設計への手引き • https://www.firebase.com/docs/android/guide/structuring-data.html
  43. 43. ご清聴ありがとうございました。
  44. 44. • 本日の資料 • http://www.slideshare.net/fumihikoshiroyama/ firebase-53320857
  45. 45. マナボはCS担当者を募集しています!

×