Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Firebase for Androidを活用した爆速アプリ開発入門

Firebase for Androidを活用した爆速アプリ開発入門

Firebase for Androidを活用した爆速アプリ開発入門

Avatar for Fumihiko Shiroyama

Fumihiko Shiroyama

November 26, 2016
Tweet

More Decks by Fumihiko Shiroyama

Other Decks in Technology

Transcript

  1. 劤傈ך،آؑٝت ˖ 'JSFCBTFך嚊銲ֶׁ׵ְ ˖ 'JSFCBTF׾⢪׏׋旗鸞Ꟛ涪 ˖ رٌ،فٔ稱➜ ˖ "OBMZUJDT ˖

    "VUIFOUJDBUJPO ˖ $SBTI3FQPSUJOH ˖ 3FBMUJNF%BUBCBTF ˖ 4UPSBHF ˖ 3FNPUF$POGJH
  2. رٌ،فٔ稱➜ ׻ְ׻ְثٍحز IUUQTQMBZHPPHMFDPNTUPSFBQQT EFUBJMT JEVTTIJSPZBNBBOESPJEGJSFCBTFSFBMUJNFDIBU ˖ ٔ،ٕة؎يثٍحز ˖ 5XJUUFS钠鏾 ˖

    ًحإ٦آך鷏⥋ ˖ 歗⫷ך،حفٗ٦س ˖ 荈ⴓך鷏׏׋ًحإ٦آך⵴ꤐ ˖ 荈ⴓך鷏׏׋歗⫷ך⵴ꤐ IUUQTHJUIVCDPNTSZN'JSFCBTF3FBM5JNF$IBU
  3. // Top-level build file
 
 buildscript {
 repositories {
 jcenter()


    mavenCentral()
 }
 dependencies {
 classpath 'com.google.gms:google-services:3.0.0'
 }
 } فٗآؙؑزךCVJMEHSBEMF
  4. // Top-level build file
 
 buildscript {
 repositories {
 jcenter()


    mavenCentral()
 }
 dependencies {
 classpath 'com.google.gms:google-services:3.0.0'
 }
 } فٗآؙؑزךCVJMEHSBEMF
  5. def firebase_lib_version = '10.0.0'
 
 dependencies {
 compile fileTree(dir: 'libs',

    include: ['*.jar'])
 
 compile "com.google.firebase:firebase-core:${firebase_lib_version}"
 }
 
 // THIS MUST BE AT THE BOTTOM
 apply plugin: 'com.google.gms.google-services' ،فٌٔآُ٦ٕךCVJMEHSBEMF
  6. ،فٌٔآُ٦ٕךCVJMEHSBEMF def firebase_lib_version = '10.0.0'
 
 dependencies {
 compile fileTree(dir:

    'libs', include: ['*.jar'])
 
 compile "com.google.firebase:firebase-core:${firebase_lib_version}"
 }
 
 // THIS MUST BE AT THE BOTTOM
 apply plugin: 'com.google.gms.google-services'
  7. "OBMZUJDT ˖ 㛇劤כֿ׸׌ֽ ˖ %"6 8"6 ."6 ˖ ،فٔך؎ٝأز٦ٕծ刿倜ծ،ٝ؎ٝ أز٦ٕ

    ˖ ぐ珏ؿ؍ٕة ˖ فٔ㹀纏ך؎كٝزך鷏⳿ ˖ 杝荈؎كٝز׮鷏⳿〳腉
  8. FirebaseAnalytics firebaseAnalytics = FirebaseAnalytics.getInstance(this);
 
 Bundle purchaseInfo = new Bundle();


    purchaseInfo.putString(FirebaseAnalytics.Param.ITEM_ID, "item_id_01234");
 purchaseInfo.putString(FirebaseAnalytics.Param.ITEM_NAME, "FANCY WATCH"); 
 firebaseAnalytics.logEvent(FirebaseAnalytics.Event.ADD_TO_CART, purchaseInfo);
  9. FirebaseAnalytics firebaseAnalytics = FirebaseAnalytics.getInstance(this);
 
 Bundle purchaseInfo = new Bundle();


    purchaseInfo.putString(FirebaseAnalytics.Param.ITEM_ID, "item_id_01234");
 purchaseInfo.putString(FirebaseAnalytics.Param.ITEM_NAME, "FANCY WATCH"); 
 firebaseAnalytics.logEvent(FirebaseAnalytics.Event.ADD_TO_CART, purchaseInfo);
  10. FirebaseAnalytics firebaseAnalytics = FirebaseAnalytics.getInstance(this);
 
 Bundle purchaseInfo = new Bundle();


    purchaseInfo.putString(FirebaseAnalytics.Param.ITEM_ID, "item_id_01234");
 purchaseInfo.putString(FirebaseAnalytics.Param.ITEM_NAME, "FANCY WATCH"); 
 firebaseAnalytics.logEvent(FirebaseAnalytics.Event.ADD_TO_CART, purchaseInfo); 'JSFCBTF"OBMZUJDT1BSBNח فٔ㹀纏ךػًٓ٦ة纇ָ֮׷
  11. FirebaseAnalytics firebaseAnalytics = FirebaseAnalytics.getInstance(this);
 
 Bundle purchaseInfo = new Bundle();


    purchaseInfo.putString(FirebaseAnalytics.Param.ITEM_ID, "item_id_01234");
 purchaseInfo.putString(FirebaseAnalytics.Param.ITEM_NAME, "FANCY WATCH"); 
 firebaseAnalytics.logEvent(FirebaseAnalytics.Event.ADD_TO_CART, purchaseInfo); 'JSFCBTF"OBMZUJDT&WFOUח فٔ㹀纏ך؎كٝز纇ָ֮׷
  12. FirebaseAnalytics firebaseAnalytics = FirebaseAnalytics.getInstance(this);
 Bundle params = new Bundle();
 params.putString("param_screen_name",

    "LoginActivity");
 firebaseAnalytics.logEvent("event_open_screen", params); 杝荈ך؎كٝزהػًٓ٦ة׾鷏׷׌ֽ
  13. FirebaseAnalytics firebaseAnalytics = FirebaseAnalytics.getInstance(this);
 Bundle params = new Bundle();
 params.putString("param_screen_name",

    "LoginActivity");
 firebaseAnalytics.logEvent("event_open_screen", params); 杝荈ך؎كٝزהػًٓ٦ة׾鷏׷׌ֽ 杝荈؎كٝزךػًٓ٦ة׾ろ׭׋ⴓ匿כ 垥彊דכ⳿勻זְךד銲#JH2VFSZ
  14. "VUIFOUJDBUJPO ˖ 'JSFCBTFך钠鏾㛇湍 ˖ 'JSFCBTF荈魦ָ*%1"44ח״׷钠鏾堣圓׾䭯׏ג ְ׷➭ծ(PPHMF 'BDFCPPL 5XJUUFS (JU)VCזו ך،ؕؐٝزד钠鏾דֹ׷ךדծ،فٔחِ٦ؠ

    钠鏾װ،ؙإأⵖ䖴׾旗鸞ד㹋鄲דֹ׷կ ˖ ⼡せךٙٝة؎ي钠鏾 ˖ 醱侧钠鏾فٗغ؎تך钠鏾䞔㜠ך窟さ ˖ ׻ְ׻ְثٍحزדכ5XJUUFS钠鏾׾ⵃ欽׃תׅ
  15. def firebase_lib_version = '10.0.0'
 
 dependencies {
 compile "com.google.firebase:firebase-core:${firebase_lib_version}" compile

    "com.google.firebase:firebase-auth:${firebase_lib_version}"
 }
 
 // THIS MUST BE AT THE BOTTOM
 apply plugin: 'com.google.gms.google-services' ،فٌٔآُ٦ٕךCVJMEHSBEMF
  16. public class MyApplication extends Application {
 
 @Override
 public void

    onCreate() {
 super.onCreate();
 
 TwitterAuthConfig authConfig = new TwitterAuthConfig(BuildConfig.TWITTER_KEY, BuildConfig.TWITTER_SECRET);
 Fabric.with(this, new Twitter(authConfig), new Crashlytics());
 }
 
 }
  17. public class MyApplication extends Application {
 
 @Override
 public void

    onCreate() {
 super.onCreate();
 
 TwitterAuthConfig authConfig = new TwitterAuthConfig(BuildConfig.TWITTER_KEY, BuildConfig.TWITTER_SECRET);
 Fabric.with(this, new Twitter(authConfig), new Crashlytics());
 }
 
 } "1*,FZ 4FDSFU
  18. @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {


    twitterLoginButton.onActivityResult(requestCode, resultCode, data);
 }
  19. @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {


    twitterLoginButton.onActivityResult(requestCode, resultCode, data);
 } 钠鏾䖓؝٦ٕغحؙ
  20. twitterLoginButton.setCallback(new Callback<TwitterSession>() {
 @Override
 public void success(Result<TwitterSession> result) {
 TwitterSession

    session = result.data;
 TwitterAuthToken token = session.getAuthToken();
 AuthCredential credential = TwitterAuthProvider.getCredential(token.token, token.secret);
 
 FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
 firebaseAuth.signInWithCredential(credential)
 .addOnSuccessListener(authResult -> {
 FirebaseUser firebaseUser = authResult.getUser();
 String uid = firebaseUser.getUid();
 UserInfo twitterUser = firebaseUser.getProviderData().get(1);
 String name = twitterUser.getDisplayName();
 String thumbnail = twitterUser.getPhotoUrl().toString();
 })
 .addOnFailureListener(e -> Log.e(TAG, e.getMessage(), e));
 }
 
 @Override
 public void failure(TwitterException exception) {
 }
 });
  21. twitterLoginButton.setCallback(new Callback<TwitterSession>() {
 @Override
 public void success(Result<TwitterSession> result) {
 TwitterSession

    session = result.data;
 TwitterAuthToken token = session.getAuthToken();
 AuthCredential credential = TwitterAuthProvider.getCredential(token.token, token.secret);
 
 FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
 firebaseAuth.signInWithCredential(credential)
 .addOnSuccessListener(authResult -> {
 FirebaseUser firebaseUser = authResult.getUser();
 String uid = firebaseUser.getUid();
 UserInfo twitterUser = firebaseUser.getProviderData().get(1);
 String name = twitterUser.getDisplayName();
 String thumbnail = twitterUser.getPhotoUrl().toString();
 })
 .addOnFailureListener(e -> Log.e(TAG, e.getMessage(), e));
 }
 
 @Override
 public void failure(TwitterException exception) {
 }
 }); ؙٔحؙ
  22. twitterLoginButton.setCallback(new Callback<TwitterSession>() {
 @Override
 public void success(Result<TwitterSession> result) {
 TwitterSession

    session = result.data;
 TwitterAuthToken token = session.getAuthToken();
 AuthCredential credential = TwitterAuthProvider.getCredential(token.token, token.secret);
 
 FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
 firebaseAuth.signInWithCredential(credential)
 .addOnSuccessListener(authResult -> {
 FirebaseUser firebaseUser = authResult.getUser();
 String uid = firebaseUser.getUid();
 UserInfo twitterUser = firebaseUser.getProviderData().get(1);
 String name = twitterUser.getDisplayName();
 String thumbnail = twitterUser.getPhotoUrl().toString();
 })
 .addOnFailureListener(e -> Log.e(TAG, e.getMessage(), e));
 }
 
 @Override
 public void failure(TwitterException exception) {
 }
 }); 5XJUUFSךز٦ؙٝ
  23. twitterLoginButton.setCallback(new Callback<TwitterSession>() {
 @Override
 public void success(Result<TwitterSession> result) {
 TwitterSession

    session = result.data;
 TwitterAuthToken token = session.getAuthToken();
 AuthCredential credential = TwitterAuthProvider.getCredential(token.token, token.secret);
 
 FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
 firebaseAuth.signInWithCredential(credential)
 .addOnSuccessListener(authResult -> {
 FirebaseUser firebaseUser = authResult.getUser();
 String uid = firebaseUser.getUid();
 UserInfo twitterUser = firebaseUser.getProviderData().get(1);
 String name = twitterUser.getDisplayName();
 String thumbnail = twitterUser.getPhotoUrl().toString();
 })
 .addOnFailureListener(e -> Log.e(TAG, e.getMessage(), e));
 }
 
 @Override
 public void failure(TwitterException exception) {
 }
 }); 'JSFCBTFך钠鏾彊⪒
  24. twitterLoginButton.setCallback(new Callback<TwitterSession>() {
 @Override
 public void success(Result<TwitterSession> result) {
 TwitterSession

    session = result.data;
 TwitterAuthToken token = session.getAuthToken();
 AuthCredential credential = TwitterAuthProvider.getCredential(token.token, token.secret);
 
 FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
 firebaseAuth.signInWithCredential(credential)
 .addOnSuccessListener(authResult -> {
 FirebaseUser firebaseUser = authResult.getUser();
 String uid = firebaseUser.getUid();
 UserInfo twitterUser = firebaseUser.getProviderData().get(1);
 String name = twitterUser.getDisplayName();
 String thumbnail = twitterUser.getPhotoUrl().toString();
 })
 .addOnFailureListener(e -> Log.e(TAG, e.getMessage(), e));
 }
 
 @Override
 public void failure(TwitterException exception) {
 }
 }); 'JSFCBTFחؚٗ؎ٝ
  25. twitterLoginButton.setCallback(new Callback<TwitterSession>() {
 @Override
 public void success(Result<TwitterSession> result) {
 TwitterSession

    session = result.data;
 TwitterAuthToken token = session.getAuthToken();
 AuthCredential credential = TwitterAuthProvider.getCredential(token.token, token.secret);
 
 FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
 firebaseAuth.signInWithCredential(credential)
 .addOnSuccessListener(authResult -> {
 FirebaseUser firebaseUser = authResult.getUser();
 String uid = firebaseUser.getUid();
 UserInfo twitterUser = firebaseUser.getProviderData().get(1);
 String name = twitterUser.getDisplayName();
 String thumbnail = twitterUser.getPhotoUrl().toString();
 })
 .addOnFailureListener(e -> Log.e(TAG, e.getMessage(), e));
 }
 
 @Override
 public void failure(TwitterException exception) {
 }
 }); 'JSFCBTFⰻךِ٦ؠ
  26. twitterLoginButton.setCallback(new Callback<TwitterSession>() {
 @Override
 public void success(Result<TwitterSession> result) {
 TwitterSession

    session = result.data;
 TwitterAuthToken token = session.getAuthToken();
 AuthCredential credential = TwitterAuthProvider.getCredential(token.token, token.secret);
 
 FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
 firebaseAuth.signInWithCredential(credential)
 .addOnSuccessListener(authResult -> {
 FirebaseUser firebaseUser = authResult.getUser();
 String uid = firebaseUser.getUid();
 UserInfo twitterUser = firebaseUser.getProviderData().get(1);
 String name = twitterUser.getDisplayName();
 String thumbnail = twitterUser.getPhotoUrl().toString();
 })
 .addOnFailureListener(e -> Log.e(TAG, e.getMessage(), e));
 }
 
 @Override
 public void failure(TwitterException exception) {
 }
 }); ♧䠐ז*%
  27. @Override
 public boolean onOptionsItemSelected(MenuItem item) {
 switch (item.getItemId()) {
 case

    R.id.action_logout:
 firebaseAuth.signOut();
 return true;
 default:
 return super.onOptionsItemSelected(item);
 }
 }
  28. @Override
 public boolean onOptionsItemSelected(MenuItem item) {
 switch (item.getItemId()) {
 case

    R.id.action_logout:
 firebaseAuth.signOut();
 return true;
 default:
 return super.onOptionsItemSelected(item);
 }
 } ؚٗ،ؐز
  29. def firebase_lib_version = '10.0.0'
 
 dependencies {
 compile "com.google.firebase:firebase-core:${firebase_lib_version}" compile

    "com.google.firebase:firebase-crash:${firebase_lib_version}"
 }
 
 // THIS MUST BE AT THE BOTTOM
 apply plugin: 'com.google.gms.google-services' ،فٌٔآُ٦ٕךCVJMEHSBEMF
  30. ر٦ة圓鸡 { "users": { "alovelace": { "name": "Ada Lovelace", "contacts":

    { "ghopper": true }, }, "ghopper": { ... }, "eclarke": { ... } } } +40/ד邌植דֹ׷⟣䠐ךر٦ة圓鸡
  31. ر٦ة圓鸡 { "users": { "alovelace": { "name": "Ada Lovelace", "contacts":

    { "ghopper": true }, }, "ghopper": { ... }, "eclarke": { ... } } } +40/ד邌植דֹ׷⟣䠐ךر٦ة圓鸡 ˟׋׌׃ٔأزכ؟ه٦زׁ׸זְ ϋογϡͰදݱ͢Δ
  32. ر٦ة圓鸡 劤傈䪔ֲر٦ة圓鸡 { "messages" : { "message01" : { "body"

    : "hello!", "senderUid" : "user0001", "type" : 0 }, ..... }, "users" : { "user01" : { "name" : "Steve", "thumbnail" : "http://example.com/img/user01.jpg" }, .... } }
  33. ر٦ة圓鸡 ًحإ٦آ׾呓秛ׅ׷خٔ٦ { "messages" : { "message01" : { "body"

    : "hello!", "senderUid" : "user0001", "type" : 0 }, ..... }, "users" : { "user01" : { "name" : "Steve", "thumbnail" : "http://example.com/img/user01.jpg" }, .... } }
  34. ر٦ة圓鸡 ِ٦ؠ׾呓秛ׅ׷خٔ٦ { "messages" : { "message01" : { "body"

    : "hello!", "senderUid" : "user0001", "type" : 0 }, ..... }, "users" : { "user01" : { "name" : "Steve", "thumbnail" : "http://example.com/img/user01.jpg" }, .... } }
  35. ر٦ة圓鸡 { "messages" : { "message01" : { "body" :

    "hello!", "senderUid" : "user0001", "type" : 0 }, "message02" : { "body" : "How are you doing? :)", "senderUid" : "user0001", "type" : 0 }, .....ʢུʣ } }
  36. ر٦ة圓鸡 { "messages" : { "message01" : { "body" :

    "hello!", "senderUid" : "user0001", "type" : 0 }, "message02" : { "body" : "How are you doing? :)", "senderUid" : "user0001", "type" : 0 }, .....ʢུʣ "message10" : { "body" : "ฦ৴͠·ͨ͠ʂ", "senderUid" : "user0002", "type" : 0 } } } ௥Ճʂ
  37. def firebase_lib_version = '10.0.0'
 
 dependencies {
 compile "com.google.firebase:firebase-core:${firebase_lib_version}" compile

    "com.google.firebase:firebase-auth:${firebase_lib_version}" compile "com.google.firebase:firebase-database:${firebase_lib_version}"
 }
 
 // THIS MUST BE AT THE BOTTOM
 apply plugin: 'com.google.gms.google-services' ،فٌٔآُ٦ٕךCVJMEHSBEMF
  38. ؎كٝزٔأشך珏겲 ٔأش ؎كٝز 欽鷿 7BMVF&WFOU-JTUFOFS PO%BUB$IBOHF ػأך؝ٝذٝخח㼎ׅ׷ 㢌刿儗חㄎל׸׷ $IJME&WFOU-JTUFOFS PO$IJME"EEFE

    ٔأزח㶨銲稆ָ鷄⸇ׁ׸ ׋儗חㄎל׸׷ $IJME&WFOU-JTUFOFS PO$IJME$IBOHFE ٔأزך㶨銲稆ח㢌刿ָ֮ ׏׋儗חㄎל׸׷ $IJME&WFOU-JTUFOFS PO$IJME3FNPWFE ٔأزך㶨銲稆ָ⵴ꤐׁ׸ ׋儗חㄎל׸׷ $IJME&WFOU-JTUFOFS PO$IJME.PWFE ٔأزך㶨銲稆ך갫䎷ָ㢌 ׻׏׋儗חㄎל׸׷
  39. ر٦ةך知⽃ז铣׫剅ֹ // Write a message to the database FirebaseDatabase database

    = FirebaseDatabase.getInstance(); DatabaseReference myRef = database.getReference("message"); myRef.setValue("Hello, World!");
  40. ر٦ةך知⽃ז剅ֹ鴥׫ // Write a message to the database FirebaseDatabase database

    = FirebaseDatabase.getInstance(); DatabaseReference myRef = database.getReference("message"); myRef.setValue("Hello, World!"); ر٦ةك٦أפ،ؙإأׅ׷彊⪒
  41. ر٦ةך知⽃ז剅ֹ鴥׫ // Write a message to the database FirebaseDatabase database

    = FirebaseDatabase.getInstance(); DatabaseReference myRef = database.getReference("message"); myRef.setValue("Hello, World!"); NFTTBHFפך⿫撑
  42. ر٦ةך知⽃ז剅ֹ鴥׫ // Write a message to the database FirebaseDatabase database

    = FirebaseDatabase.getInstance(); DatabaseReference myRef = database.getReference("message"); myRef.setValue("Hello, World!"); NFTTBHF)FMMP 8PSMEה剅ֹ鴥׫
  43. ر٦ةך知⽃ז铣׫⳿׃ FirebaseDatabase database = FirebaseDatabase.getInstance(); DatabaseReference messageRef = database.getReference("message"); ValueEventListener

    messageListener = new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { String message = dataSnapshot.getValue(String.class); } @Override public void onCancelled(DatabaseError databaseError) { } }; messageRef.addValueEventListener(messageListener); NFTTBHFפך⿫撑
  44. ر٦ةך知⽃ז铣׫⳿׃ FirebaseDatabase database = FirebaseDatabase.getInstance(); DatabaseReference messageRef = database.getReference("message"); ValueEventListener

    messageListener = new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { String message = dataSnapshot.getValue(String.class); } @Override public void onCancelled(DatabaseError databaseError) { } }; messageRef.addValueEventListener(messageListener); 7BMVF&WFOU-JTUFOFSך⡲䧭
  45. ر٦ةך知⽃ז铣׫⳿׃ FirebaseDatabase database = FirebaseDatabase.getInstance(); DatabaseReference messageRef = database.getReference("message"); ValueEventListener

    messageListener = new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { String message = dataSnapshot.getValue(String.class); } @Override public void onCancelled(DatabaseError databaseError) { } }; messageRef.addValueEventListener(messageListener); ر٦ةך《׶⳿׃
  46. ر٦ةך知⽃ז铣׫⳿׃ FirebaseDatabase database = FirebaseDatabase.getInstance(); DatabaseReference messageRef = database.getReference("message"); ValueEventListener

    messageListener = new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { String message = dataSnapshot.getValue(String.class); } @Override public void onCancelled(DatabaseError databaseError) { } }; messageRef.addValueEventListener(messageListener); ٔأشך鏣㹀
  47. ׍ז׫ח˘ ٔؿ؋ٖٝأכDIJME ד⟣䠐ך 帾ׁתד䱠׏גְֻֿהָדֹ׷ private void writeNewUser(String userId, String name,

    String email) { User user = new User(name, email); mDatabase.child("users").child(userId).setValue(user); }
  48. 7BMVF&WFOU-JTUFOFS ValueEventListener postListener = new ValueEventListener() { @Override public void

    onDataChange(DataSnapshot dataSnapshot) { // Get Post object and use the values to update the UI Post post = dataSnapshot.getValue(Post.class); // ... } @Override public void onCancelled(DatabaseError databaseError) { // Getting Post failed, log a message Log.w(TAG, "loadPost:onCancelled", databaseError.toException()); // ... } }; mPostReference.addValueEventListener(postListener);
  49. 7BMVF&WFOU-JTUFOFS ValueEventListener postListener = new ValueEventListener() { @Override public void

    onDataChange(DataSnapshot dataSnapshot) { // Get Post object and use the values to update the UI Post post = dataSnapshot.getValue(Post.class); // ... } @Override public void onCancelled(DatabaseError databaseError) { // Getting Post failed, log a message Log.w(TAG, "loadPost:onCancelled", databaseError.toException()); // ... } }; mPostReference.addValueEventListener(postListener);
  50. 7BMVF&WFOU-JTUFOFS ValueEventListener postListener = new ValueEventListener() { @Override public void

    onDataChange(DataSnapshot dataSnapshot) { // Get Post object and use the values to update the UI Post post = dataSnapshot.getValue(Post.class); // ... } @Override public void onCancelled(DatabaseError databaseError) { // Getting Post failed, log a message Log.w(TAG, "loadPost:onCancelled", databaseError.toException()); // ... } }; mPostReference.addValueEventListener(postListener);
  51. 7BMVF&WFOU-JTUFOFS ValueEventListener postListener = new ValueEventListener() { @Override public void

    onDataChange(DataSnapshot dataSnapshot) { // Get Post object and use the values to update the UI Post post = dataSnapshot.getValue(Post.class); // ... } @Override public void onCancelled(DatabaseError databaseError) { // Getting Post failed, log a message Log.w(TAG, "loadPost:onCancelled", databaseError.toException()); // ... } }; mPostReference.addValueEventListener(postListener);
  52. 7BMVF&WFOU-JTUFOFS ValueEventListener postListener = new ValueEventListener() { @Override public void

    onDataChange(DataSnapshot dataSnapshot) { // Get Post object and use the values to update the UI Post post = dataSnapshot.getValue(Post.class); // ... } @Override public void onCancelled(DatabaseError databaseError) { // Getting Post failed, log a message Log.w(TAG, "loadPost:onCancelled", databaseError.toException()); // ... } }; mPostReference.addValueEventListener(postListener); ⥂㶷׮铣׫⳿׃׮⟣䠐ך10+0ָ⢪欽〳腉
  53. $IJME&WFOU-JTUFOFS ChildEventListener childEventListener = new ChildEventListener() { @Override public void

    onChildAdded(DataSnapshot dataSnapshot, String previousChildName) { Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey()); // A new comment has been added, add it to the displayed list Comment comment = dataSnapshot.getValue(Comment.class); // ... }
  54. $IJME&WFOU-JTUFOFS ChildEventListener childEventListener = new ChildEventListener() { @Override public void

    onChildAdded(DataSnapshot dataSnapshot, String previousChildName) { Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey()); // A new comment has been added, add it to the displayed list Comment comment = dataSnapshot.getValue(Comment.class); // ... } PO$IJME"EEFE כ㶨銲稆ך鷄⸇
  55. $IJME&WFOU-JTUFOFS @Override public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) { Log.d(TAG,

    "onChildChanged:" + dataSnapshot.getKey()); // A comment has changed, use the key to determine if we are displaying this // comment and if so displayed the changed comment. Comment newComment = dataSnapshot.getValue(Comment.class); String commentKey = dataSnapshot.getKey(); // ... }
  56. $IJME&WFOU-JTUFOFS @Override public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) { Log.d(TAG,

    "onChildChanged:" + dataSnapshot.getKey()); // A comment has changed, use the key to determine if we are displaying this // comment and if so displayed the changed comment. Comment newComment = dataSnapshot.getValue(Comment.class); String commentKey = dataSnapshot.getKey(); // ... } PO$IJME$IBOHFE כ㶨銲稆ך㢌⻉
  57. $IJME&WFOU-JTUFOFS @Override public void onChildRemoved(DataSnapshot dataSnapshot) { Log.d(TAG, "onChildRemoved:" +

    dataSnapshot.getKey()); // A comment has changed, use the key to determine if we are displaying this // comment and if so remove it. String commentKey = dataSnapshot.getKey(); // ... }
  58. $IJME&WFOU-JTUFOFS @Override public void onChildRemoved(DataSnapshot dataSnapshot) { Log.d(TAG, "onChildRemoved:" +

    dataSnapshot.getKey()); // A comment has changed, use the key to determine if we are displaying this // comment and if so remove it. String commentKey = dataSnapshot.getKey(); // ... } PO$IJME3FNPWFE כ㶨銲稆ך⵴ꤐ
  59. $IJME&WFOU-JTUFOFS @Override public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) { Log.d(TAG,

    "onChildMoved:" + dataSnapshot.getKey()); // A comment has changed position, use the key to determine if we are // displaying this comment and if so move it. Comment movedComment = dataSnapshot.getValue(Comment.class); String commentKey = dataSnapshot.getKey(); // ... }
  60. $IJME&WFOU-JTUFOFS @Override public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) { Log.d(TAG,

    "onChildMoved:" + dataSnapshot.getKey()); // A comment has changed position, use the key to determine if we are // displaying this comment and if so move it. Comment movedComment = dataSnapshot.getValue(Comment.class); String commentKey = dataSnapshot.getKey(); // ... } PO$IJME.PWFE כ㶨銲稆ך갫殢Ⰵ剏
  61. $IJME&WFOU-JTUFOFS @Override public void onCancelled(DatabaseError databaseError) { Log.w(TAG, "postComments:onCancelled", databaseError.toException());

    Toast.makeText(mContext, "Failed to load comments.", Toast.LENGTH_SHORT).show(); } }; ref.addChildEventListener(childEventListener);
  62. $IJME&WFOU-JTUFOFS @Override public void onCancelled(DatabaseError databaseError) { Log.w(TAG, "postComments:onCancelled", databaseError.toException());

    Toast.makeText(mContext, "Failed to load comments.", Toast.LENGTH_SHORT).show(); } }; ref.addChildEventListener(childEventListener); BEE$IJME&WFOU-JTUFOFSחإحز 埄ꣲךؒٓ٦瘝
  63. ٔأزח㶨銲稆׾鷄⸇ DatabaseReference newMessageRef = databaseReference.child("/messages").push();
 
 newMessageRef
 .setValue(message)
 .addOnSuccessListener(result ->

    Log.d(TAG, "try message send."))
 .addOnFailureListener(error -> handleError(error, R.string.message_sent_error)); QVTI דة؎يأةٝفח㛇בֻLFZָ荈⹛涪遤ׁ׸׷
  64. ٔأزח㶨銲稆׾鷄⸇ DatabaseReference newMessageRef = databaseReference.child("/messages").push();
 
 newMessageRef
 .setValue(message)
 .addOnSuccessListener(result ->

    Log.d(TAG, "try message send."))
 .addOnFailureListener(error -> handleError(error, R.string.message_sent_error)); ֮הכֿ׸תדず圫TFU7BMVFׅ׷׌ֽ
  65. 銲稆ך⚛ן剏ִ String myUserId = getUid(); Query myTopPostsQuery = databaseReference.child("user-posts").child(myUserId) .orderByChild("starCount");

    myTopPostsQuery.addChildEventListener(new ChildEventListener() { // TODO: implement the ChildEventListener methods as documented above // ... });
  66. 銲稆ך⚛ן剏ִ String myUserId = getUid(); Query myTopPostsQuery = databaseReference.child("user-posts").child(myUserId) .orderByChild("starCount");

    myTopPostsQuery.addChildEventListener(new ChildEventListener() { // TODO: implement the ChildEventListener methods as documented above // ... }); ⟣䠐ךٔؿ؋ٖٝأ׾⿫撑
  67. 銲稆ך⚛ן剏ִ String myUserId = getUid(); Query myTopPostsQuery = databaseReference.child("user-posts").child(myUserId) .orderByChild("starCount");

    myTopPostsQuery.addChildEventListener(new ChildEventListener() { // TODO: implement the ChildEventListener methods as documented above // ... }); ا٦ز勴⟝׾䭷㹀
  68. 銲稆ך⚛ן剏ִ String myUserId = getUid(); Query myTopPostsQuery = databaseReference.child("user-posts").child(myUserId) .orderByChild("starCount");

    myTopPostsQuery.addChildEventListener(new ChildEventListener() { // TODO: implement the ChildEventListener methods as documented above // ... }); ֿ׸תד鸐׶ٔأش׾إحز
  69. def firebase_lib_version = '10.0.0'
 
 dependencies {
 compile "com.google.firebase:firebase-core:${firebase_lib_version}" compile

    "com.google.firebase:firebase-auth:${firebase_lib_version}" compile "com.google.firebase:firebase-storage:${firebase_lib_version}"
 }
 
 // THIS MUST BE AT THE BOTTOM
 apply plugin: 'com.google.gms.google-services' ،فٌٔآُ٦ٕךCVJMEHSBEMF
  70. 4UPSBHF FirebaseStorage storage = FirebaseStorage.getInstance(); StorageReference storageRef = storage.getReferenceFromUrl("gs://<your-bucket-name>"); StorageReference

    imagesRef = storageRef.child("images"); StorageReference spaceRef = storageRef.child("images/space.jpg"); spaceRef.getPath(); spaceRef.getName(); spaceRef.getBucket();
  71. 4UPSBHF FirebaseStorage storage = FirebaseStorage.getInstance(); StorageReference storageRef = storage.getReferenceFromUrl("gs://<your-bucket-name>"); StorageReference

    imagesRef = storageRef.child("images"); StorageReference spaceRef = storageRef.child("images/space.jpg"); spaceRef.getPath(); spaceRef.getName(); spaceRef.getBucket();
  72. 4UPSBHF FirebaseStorage storage = FirebaseStorage.getInstance(); StorageReference storageRef = storage.getReferenceFromUrl("gs://<your-bucket-name>"); StorageReference

    imagesRef = storageRef.child("images"); StorageReference spaceRef = storageRef.child("images/space.jpg"); spaceRef.getPath(); spaceRef.getName(); spaceRef.getBucket();
  73. 4UPSBHF FirebaseStorage storage = FirebaseStorage.getInstance(); StorageReference storageRef = storage.getReferenceFromUrl("gs://<your-bucket-name>"); StorageReference

    imagesRef = storageRef.child("images"); StorageReference spaceRef = storageRef.child("images/space.jpg"); spaceRef.getPath(); spaceRef.getName(); spaceRef.getBucket();
  74. 4UPSBHF FirebaseStorage storage = FirebaseStorage.getInstance(); StorageReference storageRef = storage.getReferenceFromUrl("gs://<your-bucket-name>"); StorageReference

    imagesRef = storageRef.child("images"); StorageReference spaceRef = storageRef.child("images/space.jpg"); spaceRef.getPath(); spaceRef.getName(); spaceRef.getBucket();
  75. 4UPSBHFח،حفٗ٦س public void uploadImage(String filePath, boolean deletePath) {
 String fileName

    = UUID.randomUUID().toString();
 StorageReference target = storageReference
 .child(IMG_DIR)
 .child(fileName);
 
 try {
 InputStream inputStream = new BufferedInputStream(new FileInputStream(filePath));
 target.putStream(inputStream)
 .addOnSuccessListener(taskSnapshot -> {
 Log.d(TAG, "upload succeeded.");
 long totalBytes = taskSnapshot.getTotalByteCount();
 Uri downloadUri = taskSnapshot.getDownloadUrl();
 })
 .addOnFailureListener(e -> Log.e(TAG, e.getMessage(), e));
 } catch (FileNotFoundException e) {
 Log.e(TAG, e.getMessage(), e);
 }
 }
  76. 4UPSBHFח،حفٗ٦س public void uploadImage(String filePath, boolean deletePath) {
 String fileName

    = UUID.randomUUID().toString();
 StorageReference target = storageReference
 .child(IMG_DIR)
 .child(fileName);
 
 try {
 InputStream inputStream = new BufferedInputStream(new FileInputStream(filePath));
 target.putStream(inputStream)
 .addOnSuccessListener(taskSnapshot -> {
 Log.d(TAG, "upload succeeded.");
 long totalBytes = taskSnapshot.getTotalByteCount();
 Uri downloadUri = taskSnapshot.getDownloadUrl();
 })
 .addOnFailureListener(e -> Log.e(TAG, e.getMessage(), e));
 } catch (FileNotFoundException e) {
 Log.e(TAG, e.getMessage(), e);
 }
 }
  77. 4UPSBHFח،حفٗ٦س public void uploadImage(String filePath, boolean deletePath) {
 String fileName

    = UUID.randomUUID().toString();
 StorageReference target = storageReference
 .child(IMG_DIR)
 .child(fileName);
 
 try {
 InputStream inputStream = new BufferedInputStream(new FileInputStream(filePath));
 target.putStream(inputStream)
 .addOnSuccessListener(taskSnapshot -> {
 Log.d(TAG, "upload succeeded.");
 long totalBytes = taskSnapshot.getTotalByteCount();
 Uri downloadUri = taskSnapshot.getDownloadUrl();
 })
 .addOnFailureListener(e -> Log.e(TAG, e.getMessage(), e));
 } catch (FileNotFoundException e) {
 Log.e(TAG, e.getMessage(), e);
 }
 }
  78. 4UPSBHFח،حفٗ٦س public void uploadImage(String filePath, boolean deletePath) {
 String fileName

    = UUID.randomUUID().toString();
 StorageReference target = storageReference
 .child(IMG_DIR)
 .child(fileName);
 
 try {
 InputStream inputStream = new BufferedInputStream(new FileInputStream(filePath));
 target.putStream(inputStream)
 .addOnSuccessListener(taskSnapshot -> {
 Log.d(TAG, "upload succeeded.");
 long totalBytes = taskSnapshot.getTotalByteCount();
 Uri downloadUri = taskSnapshot.getDownloadUrl();
 })
 .addOnFailureListener(e -> Log.e(TAG, e.getMessage(), e));
 } catch (FileNotFoundException e) {
 Log.e(TAG, e.getMessage(), e);
 }
 }
  79. 4UPSBHFח،حفٗ٦س public void uploadImage(String filePath, boolean deletePath) {
 String fileName

    = UUID.randomUUID().toString();
 StorageReference target = storageReference
 .child(IMG_DIR)
 .child(fileName);
 
 try {
 InputStream inputStream = new BufferedInputStream(new FileInputStream(filePath));
 target.putStream(inputStream)
 .addOnSuccessListener(taskSnapshot -> {
 Log.d(TAG, "upload succeeded.");
 long totalBytes = taskSnapshot.getTotalByteCount();
 Uri downloadUri = taskSnapshot.getDownloadUrl();
 })
 .addOnFailureListener(e -> Log.e(TAG, e.getMessage(), e));
 } catch (FileNotFoundException e) {
 Log.e(TAG, e.getMessage(), e);
 }
 }
  80. 4UPSBHFח،حفٗ٦س public void uploadImage(String filePath, boolean deletePath) {
 String fileName

    = UUID.randomUUID().toString();
 StorageReference target = storageReference
 .child(IMG_DIR)
 .child(fileName);
 
 try {
 InputStream inputStream = new BufferedInputStream(new FileInputStream(filePath));
 target.putStream(inputStream)
 .addOnSuccessListener(taskSnapshot -> {
 Log.d(TAG, "upload succeeded.");
 long totalBytes = taskSnapshot.getTotalByteCount();
 Uri downloadUri = taskSnapshot.getDownloadUrl();
 })
 .addOnFailureListener(e -> Log.e(TAG, e.getMessage(), e));
 } catch (FileNotFoundException e) {
 Log.e(TAG, e.getMessage(), e);
 }
 } ؙٓ؎،ٝزכֿ׸׾تؐٝٗ٦س
  81. 4UPSBHFַ׵⵴ꤐ public void deleteImage(String fileName) {
 StorageReference target = storageReference


    .child(IMG_DIR)
 .child(fileName);
 target.delete()
 .addOnSuccessListener(result -> Log.d(TAG, "image delete ok."))
 .addOnFailureListener(error -> Log.e(TAG, error.getMessage(), error));
 }
  82. 4UPSBHFַ׵⵴ꤐ public void deleteImage(String fileName) {
 StorageReference target = storageReference


    .child(IMG_DIR)
 .child(fileName);
 target.delete()
 .addOnSuccessListener(result -> Log.d(TAG, "image delete ok."))
 .addOnFailureListener(error -> Log.e(TAG, error.getMessage(), error));
 }
  83. 4UPSBHFַ׵⵴ꤐ public void deleteImage(String fileName) {
 StorageReference target = storageReference


    .child(IMG_DIR)
 .child(fileName);
 target.delete()
 .addOnSuccessListener(result -> Log.d(TAG, "image delete ok."))
 .addOnFailureListener(error -> Log.e(TAG, error.getMessage(), error));
 }
  84. 4UPSBHFַ׵⵴ꤐ public void deleteImage(String fileName) {
 StorageReference target = storageReference


    .child(IMG_DIR)
 .child(fileName);
 target.delete()
 .addOnSuccessListener(result -> Log.d(TAG, "image delete ok."))
 .addOnFailureListener(error -> Log.e(TAG, error.getMessage(), error));
 }
  85. def firebase_lib_version = '10.0.0'
 
 dependencies {
 compile "com.google.firebase:firebase-core:${firebase_lib_version}" compile

    "com.google.firebase:firebase-auth:${firebase_lib_version}" compile "com.google.firebase:firebase-storage:${firebase_lib_version}" compile "com.google.firebase:firebase-config:${firebase_lib_version}"
 }
 
 // THIS MUST BE AT THE BOTTOM
 apply plugin: 'com.google.gms.google-services' ،فٌٔآُ٦ٕךCVJMEHSBEMF
  86. 3FNPUF$POGJH FirebaseRemoteConfigSettings remoteConfigSettings = new FirebaseRemoteConfigSettings.Builder()
 .setDeveloperModeEnabled(BuildConfig.DEBUG)
 .build();
 
 FirebaseRemoteConfig

    firebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
 firebaseRemoteConfig.setConfigSettings(remoteConfigSettings);
 firebaseRemoteConfig.setDefaults(R.xml.remote_config_defaults);
 
 if (firebaseRemoteConfig.getInfo().getConfigSettings().isDeveloperModeEnabled()) {
 cacheExpiration = 0;
 }
 
 firebaseRemoteConfig.fetch(cacheExpiration)
 .addOnSuccessListener(result -> Log.d(TAG, "Fetch succeeded."))
 .addOnFailureListener(e -> Log.e(TAG, "Fetch failed.", e));
  87. 3FNPUF$POGJH FirebaseRemoteConfigSettings remoteConfigSettings = new FirebaseRemoteConfigSettings.Builder()
 .setDeveloperModeEnabled(BuildConfig.DEBUG)
 .build();
 
 FirebaseRemoteConfig

    firebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
 firebaseRemoteConfig.setConfigSettings(remoteConfigSettings);
 firebaseRemoteConfig.setDefaults(R.xml.remote_config_defaults);
 
 if (firebaseRemoteConfig.getInfo().getConfigSettings().isDeveloperModeEnabled()) {
 cacheExpiration = 0;
 }
 
 firebaseRemoteConfig.fetch(cacheExpiration)
 .addOnSuccessListener(result -> Log.d(TAG, "Fetch succeeded."))
 .addOnFailureListener(e -> Log.e(TAG, "Fetch failed.", e));
  88. 3FNPUF$POGJH FirebaseRemoteConfigSettings remoteConfigSettings = new FirebaseRemoteConfigSettings.Builder()
 .setDeveloperModeEnabled(BuildConfig.DEBUG)
 .build();
 
 FirebaseRemoteConfig

    firebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
 firebaseRemoteConfig.setConfigSettings(remoteConfigSettings);
 firebaseRemoteConfig.setDefaults(R.xml.remote_config_defaults);
 
 if (firebaseRemoteConfig.getInfo().getConfigSettings().isDeveloperModeEnabled()) {
 cacheExpiration = 0;
 }
 
 firebaseRemoteConfig.fetch(cacheExpiration)
 .addOnSuccessListener(result -> Log.d(TAG, "Fetch succeeded."))
 .addOnFailureListener(e -> Log.e(TAG, "Fetch failed.", e));
  89. 3FNPUF$POGJH FirebaseRemoteConfigSettings remoteConfigSettings = new FirebaseRemoteConfigSettings.Builder()
 .setDeveloperModeEnabled(BuildConfig.DEBUG)
 .build();
 
 FirebaseRemoteConfig

    firebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
 firebaseRemoteConfig.setConfigSettings(remoteConfigSettings);
 firebaseRemoteConfig.setDefaults(R.xml.remote_config_defaults);
 
 if (firebaseRemoteConfig.getInfo().getConfigSettings().isDeveloperModeEnabled()) {
 cacheExpiration = 0;
 }
 
 firebaseRemoteConfig.fetch(cacheExpiration)
 .addOnSuccessListener(result -> Log.d(TAG, "Fetch succeeded."))
 .addOnFailureListener(e -> Log.e(TAG, "Fetch failed.", e));
  90. 3FNPUF$POGJH FirebaseRemoteConfigSettings remoteConfigSettings = new FirebaseRemoteConfigSettings.Builder()
 .setDeveloperModeEnabled(BuildConfig.DEBUG)
 .build();
 
 FirebaseRemoteConfig

    firebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
 firebaseRemoteConfig.setConfigSettings(remoteConfigSettings);
 firebaseRemoteConfig.setDefaults(R.xml.remote_config_defaults);
 
 if (firebaseRemoteConfig.getInfo().getConfigSettings().isDeveloperModeEnabled()) {
 cacheExpiration = 0;
 }
 
 firebaseRemoteConfig.fetch(cacheExpiration)
 .addOnSuccessListener(result -> Log.d(TAG, "Fetch succeeded."))
 .addOnFailureListener(e -> Log.e(TAG, "Fetch failed.", e));
  91. 3FNPUF$POGJH public void setBackgroundColor(View target) {
 String colorHex = firebaseRemoteConfig.getString("chat_bg_color");


    Log.d(TAG, "colorHex: " + colorHex);
 int color = Color.parseColor(colorHex);
 target.setBackgroundColor(color);
 }
  92. 3FNPUF$POGJH public void setBackgroundColor(View target) {
 String colorHex = firebaseRemoteConfig.getString("chat_bg_color");


    Log.d(TAG, "colorHex: " + colorHex);
 int color = Color.parseColor(colorHex);
 target.setBackgroundColor(color);
 }
  93. ׉ך➭5JQT private ValueEventListener singleShotListener = new ValueEventListener() {
 @Override
 public

    void onDataChange(DataSnapshot dataSnapshot) {
 for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
 Message message = getMessageWithId(snapshot); // தུ
 updateTimestamp(message.getTimestamp());
 } ɹɹɹɹɹ// தུ
 
 databaseReference.child(Message.PATH) .orderByChild(Message.KEY_TIMESTAMP) .startAt(lastTimestamp + 1) .addChildEventListener(childAddListener);
 }
 
 @Override
 public void onCancelled(DatabaseError databaseError) { }
 };
  94. ׉ך➭5JQT private ValueEventListener singleShotListener = new ValueEventListener() {
 @Override
 public

    void onDataChange(DataSnapshot dataSnapshot) {
 for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
 Message message = getMessageWithId(snapshot); // தུ
 updateTimestamp(message.getTimestamp());
 } ɹɹɹɹɹ// தུ
 
 databaseReference.child(Message.PATH) .orderByChild(Message.KEY_TIMESTAMP) .startAt(lastTimestamp + 1) .addChildEventListener(childAddListener);
 }
 
 @Override
 public void onCancelled(DatabaseError databaseError) { }
 };
  95. ׉ך➭5JQT private ValueEventListener singleShotListener = new ValueEventListener() {
 @Override
 public

    void onDataChange(DataSnapshot dataSnapshot) {
 for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
 Message message = getMessageWithId(snapshot); // தུ
 updateTimestamp(message.getTimestamp());
 } ɹɹɹɹɹ// தུ
 
 databaseReference.child(Message.PATH) .orderByChild(Message.KEY_TIMESTAMP) .startAt(lastTimestamp + 1) .addChildEventListener(childAddListener);
 }
 
 @Override
 public void onCancelled(DatabaseError databaseError) { }
 };
  96. ׉ך➭5JQT private ValueEventListener singleShotListener = new ValueEventListener() {
 @Override
 public

    void onDataChange(DataSnapshot dataSnapshot) {
 for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
 Message message = getMessageWithId(snapshot); // தུ
 updateTimestamp(message.getTimestamp());
 } ɹɹɹɹɹ// தུ
 
 databaseReference.child(Message.PATH) .orderByChild(Message.KEY_TIMESTAMP) .startAt(lastTimestamp + 1) .addChildEventListener(childAddListener);
 }
 
 @Override
 public void onCancelled(DatabaseError databaseError) { }
 };
  97. ׉ך➭5JQT private ValueEventListener singleShotListener = new ValueEventListener() {
 @Override
 public

    void onDataChange(DataSnapshot dataSnapshot) {
 for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
 Message message = getMessageWithId(snapshot); // தུ
 updateTimestamp(message.getTimestamp());
 } ɹɹɹɹɹ// தུ
 
 databaseReference.child(Message.PATH) .orderByChild(Message.KEY_TIMESTAMP) .startAt(lastTimestamp + 1) .addChildEventListener(childAddListener);
 }
 
 @Override
 public void onCancelled(DatabaseError databaseError) { }
 };
  98. ׉ך➭5JQT { "rules": { ".read": false, ".write": false, "users": {

    ".read": "auth != null", "$user_id": { ".write": "auth != null && auth.uid === $user_id" } }, "messages": { ".read": "auth != null", ".indexOn": ["timestamp"], "$message_id": { ".write": "(auth != null && auth.uid === newData.child('senderUid').val()) || (auth != null && auth.uid === data.child('senderUid').val())" } } }, }
  99. ׉ך➭5JQT { "rules": { ".read": false, ".write": false, "users": {

    ".read": "auth != null", "$user_id": { ".write": "auth != null && auth.uid === $user_id" } }, "messages": { ".read": "auth != null", ".indexOn": ["timestamp"], "$message_id": { ".write": "(auth != null && auth.uid === newData.child('senderUid').val()) || (auth != null && auth.uid === data.child('senderUid').val())" } } }, } 钠鏾幥׫
  100. ׉ך➭5JQT { "rules": { ".read": false, ".write": false, "users": {

    ".read": "auth != null", "$user_id": { ".write": "auth != null && auth.uid === $user_id" } }, "messages": { ".read": "auth != null", ".indexOn": ["timestamp"], "$message_id": { ".write": "(auth != null && auth.uid === newData.child('senderUid').val()) || (auth != null && auth.uid === data.child('senderUid').val())" } } }, } 倜׃ֻ剅ֹ鴥ת׸׷ر٦ة
  101. ׉ך➭5JQT { "rules": { ".read": false, ".write": false, "users": {

    ".read": "auth != null", "$user_id": { ".write": "auth != null && auth.uid === $user_id" } }, "messages": { ".read": "auth != null", ".indexOn": ["timestamp"], "$message_id": { ".write": "(auth != null && auth.uid === newData.child('senderUid').val()) || (auth != null && auth.uid === data.child('senderUid').val())" } } }, } ֿ׸ַ׵⵴ꤐׅ׷ر٦ة