Day 30 - Firebase
สวัสดีครับ บทความนี้เป็นบทความที่ 30 บทความสุดท้ายแล้วนะครับ ใครที่ติดตามอ่านอยู่ก็ขอขอบคุณมากเลยครับ :D
สำหรับบทความทั้งหมด อ่านได้จากด้านล่างครับ
- Day 1 : AndroidStaggered Grid
- Day 2 : Paralloid
- Day 3 : Retrofit
- Day 4 : SwipeRefreshLayout
- Day 5 : Android GraphView
- Day 6 : Holo Color Picker
- Day 7 : Android Async Http
- Day 8 : Crashlytics
- Day 9 : Butter Knife
- Day 10 : Android Annotations
- Day 11 : DateTimePicker
- Day 12 : Circular Progress Button
- Day 13 : ViewPager
- Day 14 : ViewPagerIndicator
- Day 15 : FadingActionBar
- Day 16 : AutofitTextView
- Day 17 : SwipeListView
- Day 18 : ShowcaseView
- Day 19 : GreenDAO
- Day 20 : AndroidViewAnimation
- Day 21 : ActiveAndroid
- Day 22 : Twitter4J
- Day 23 : ListViewAnimations
- Day 24 : AndEngine
- Day 25 : EazeGraph
- Day 26 : Cardslib
- Day 27 : AdapterKit
- Day 28 : WeatherLib
- Day 29 : FlatUI
- Day 30 : Android Firebase
สำหรับวันนี้ขอนำเสนอเรื่อง Firebase
Firebase เป็น Real Time App Platform คือให้บริการ API สำหรับการส่งข้อมูลแบบ Real Time รองรับหลาย Platform สามารถเขียนได้หลายภาษา รายละเอียดเพิ่มเติม อ่านได้ที่เว็บ Firebase เลยครับ
สำหรับบทความนี้ จะใช้ Firebase API มาใช้ในการทำแอพ Chat บน Android นะครับ เป็นแอพง่ายๆ มาเริ่มทำกันเลยดีกว่า
Register
เริ่มแรก ต้องทำการสมัคร Firebase ซะก่อน การสมัครไม่ยุ่่งยากเลย ขอข้ามส่วนนี้ไปเลยละกันครับ เมื่อสมัครเสร็จเรียบร้อย ทุกคนจะมีหน้า Dashboard เป็นของตนเอง
แต่ว่าเมื่อสมัครเข้ามาแล้ว จะมี Guide ให้เราอ่านมากมายครับ เช่น Example, Tutorial, Quick Start, API Docs ก็อ่านประกอบๆ ด้วยก็ดีนะครับ
กดสร้าง App ใหม่ได้เลยครับ เมื่อสร้างเสร็จ เราจะได้หน้าไว้จัดการข้อมูล โดยเป็น https://ชื่อแอพที่ตั้ง.firebaseio.com
เช่นของผมเป็น https://ahoychat.firebaseio.com/
หน้าตาจัดการ Firebase ของเราจะเป็นประมาณนี้
ทีนี้ในส่วนหน้าเว็บ ก็หยุดไว้แค่นี้ครับ สร้างแอพมาแล้ว ต่อไปก็เป็นการติดตั้ง Firebase Client เพื่อใช้ในแอพ Android
Installation
ขั้นตอนการติดตั้ง เปิดไฟล์ build.gradle
ขึ้นมา แล้วเพิ่ม dependencies ลงไปดังนี้
dependencies {
compile 'com.firebase:firebase-client:1.0.16+'
}
กด Sync Gradle เป็นอันเรียบร้อย
อย่าลืมเพิ่ม permission INTERNET ในไฟล์ AndroidManifest.xml
ด้วยนะครับ
<uses-permission android:name="android.permission.INTERNET" />
Usage
การใช้งาน Firebase เบื้องต้นนะครับ เริ่มแรกต้องทำการสร้าง ออปเจ็ค reference ให้มันก่อน โดยใช้ URL ที่ได้ตอนเราสร้างแอพผ่านหน้าเว็บอะครับ
Firebase firebase = new Firebase("https://<your-firebase>.firebaseio.com/");
Firebase จะเก็บข้อมูลทั้งหมดในรูปแบบ JSON นะครับ
การเซฟข้อมูล
ตัวอย่างการเซฟข้อมูล ตามโค๊ดด้านล่าง
firebase.child("message").setValue("Do you have data? You'll love Firebase.");
การอ่านข้อมูล
การอ่านข้อมูล จะใช้ Listener
เข้ามาช่วยครับ เมื่อมีข้อมูลถูกเพิ่มเข้ามา ก็จะส่ง event กลับมาครับ ตามข้างล่างนี้
firebase.child("message").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
System.out.println(snapshot.getValue()); //prints "Do you have data? You'll love Firebase."
}
@Override public void onCancelled(FirebaseError error) { }
});
โค๊ดทั้งหมดนี้ ผมเอามาจาก Docs เลยนะครับ จริงๆ อ่านจาก Docs น่าจะเข้าใจง่ายกว่านะ มาลองเริ่มทำโปรเจ็คเล็กๆกันดูครับ :D
Create Project
หลักจากที่เราทำการเพิ่ม dependencies เรียบร้อยแล้ว ต่อมา สร้างเลเอาท์ก่อนเลยครับ จะใช้เลเอาท์ไฟล์เดียวนะครับ สมมติชื่อ activity_firebase.xml
ภายในเลเอาท์ประกอบไปด้วย
ListView
: สำหรับแสดงข้อความแชตEditText
: สำหรับพิมพ์ข้อความImageButton
: สำหรับกดเมื่อต้องการส่งข้อความ
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/linear"
android:id="@+id/list_view" />
<LinearLayout android:id="@+id/linear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
<EditText
android:id="@+id/message"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_weight="1"
android:lines="1"
android:inputType="textShortMessage"
android:singleLine="true" />
<ImageButton
android:id="@+id/button_send"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@android:drawable/ic_menu_send" />
</LinearLayout>
</RelativeLayout>
ต่อมาสร้างไฟล์ FirebaseActivity.java
ขึ้นมา ดังนี้
package com.devahoy.learn30androidlibraries.day30;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import com.devahoy.learn30androidlibraries.R;
import com.firebase.client.ChildEventListener;
import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import com.firebase.client.Query;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
public class FireBaseActivity extends ActionBarActivity {
private static final String AHOY_CHAT_URL = "https://ahoychat.firebaseio.com";
private List<String> mChats = new ArrayList<String>();
private ListView mListView;
private ArrayAdapter<String> mAdapter;
private ImageButton mButtonSend;
private EditText mMessage;
private Firebase mFirebase;
private String mUsername;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Random r = new Random();
mUsername = "AhoyUser" + r.nextInt(1000);
setContentView(R.layout.day30_activity_firebase);
mButtonSend = (ImageButton) findViewById(R.id.button_send);
mMessage = (EditText) findViewById(R.id.message);
mListView = (ListView) findViewById(R.id.list_view);
mListView.setBackgroundColor(Color.parseColor("#26B895"));
mFirebase = new Firebase(AHOY_CHAT_URL).child("chat");
queryData();
mButtonSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendMessage();
}
});
}
private void sendMessage() {
// Chat chat = new Chat(mMessage.getText().toString(), mUsername);
Map<String, Object> chat = new HashMap<String, Object>();
chat.put("owner", mUsername);
chat.put("message", mMessage.getText().toString());
mFirebase.push().setValue(chat);
mMessage.setText("");
}
private void queryData() {
Query query = mFirebase.limit(10);
query.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Map<String, Object> newPost = (Map<String, Object>) dataSnapshot.getValue();
String owner = newPost.get("owner").toString();
String message = newPost.get("message").toString();
mChats.add(0, owner + " Say: " + message);
if (mAdapter == null) {
mAdapter = new ArrayAdapter<String>(getApplicationContext(),
android.R.layout.simple_list_item_1, mChats);
mListView.setAdapter(mAdapter);
}
mAdapter.notifyDataSetChanged();
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
mAdapter.notifyDataSetChanged();
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
}
จากโค๊ดด้านบน เริ่มไล่ตั้งแ่ต่ onCreate()
เลยนะครับ ภายในเมธอดนี้เราก็ทำการ findView ให้หมด จากนั้นอ้าง Reference ของ Firebase ด้วย new Firebase("url").child("chat");
ใส่ url ของเรา และอ้างอิง child ที่ชือว่า chat จากนั้นก็มี call เมธอด queryData()
ในส่วนนี้จะเป็นการ Query เพื่อเอาข้อมูลจาก Firebase มาแสดง เมธอด sendMessage()
ทำการรับข้อความจาก EditText ทีเรากรอกลงไป จากนั้นก็ใช้ Map<String, Object>
เพื่อทำการแมพ key, value ชื่อ owner และ message เพื่อส่งไปยัง Firebase โดยใช้คำสั่ง mFirebase.push().setValue(chat);
เพื่อส่งข้อมูล จริงๆ ส่วนนี้จะใช้เป็นคลาส Model ก็ได้นะครับ ตามที่ผม comment ไว้ ส่วนคลาส Chat ดูได้จากนี้
ต่อมาที่เมธอด queryData()
จะเห็นคำสั่ง Query query = mFirebase.limit(10);
คือการเรียกข้อมูลจาก Firebase มาแสดง จำกัดแค่ 10 ค่า จากนั้นใช้ addChildEventListener
โดยมี Listener เป็น ChildEventListener()
ส่วนที่เราสนใจคือ เมธอด onChildAdded()
ในส่วนนี้จะ call เมื่อมีการเพิ่มข้อมูลใน Firebase ทั้งจากแอพของเรา จากทางบราวเซอร์ หรือจากเครื่องอื่นๆ ที่ใช้แอพนี้ ฉะนั้นส่วนนี้ก็เลยเป็นส่วนที่ผมเอาไว้ สร้าง ListView ครับ
การ getValue() จาก Firebase ในเมธอด onChildAdded()
จะมี DataSnapshot
ส่งมาด้วย ตัวนี้ เราจะได้ค่าจาก คำสั่งนี้
Map<String, Object> newPost = (Map<String, Object>) dataSnapshot.getValue();
String owner = newPost.get("owner").toString();
String message = newPost.get("message").toString();
คือหา key ที่มีคำว่า owner และ message ซึ่งเป็นคีย์เดียวกันกับตอนที่เรากด sendData ส่วนที่เหลือก็เป็นการสร้าง ArrayAdapter และ setAdapter ธรรมดาครับ
ลองดูใน Browser ก็เป็นข้อมูลชนิดเดียวกัน
ผลลัพธ์ที่ได้ ก็ประมาณนี้
สรุป
ตัว Firebase ก็น่าสนใจไม่น้อยเลย จำได้ว่าเคยได้ยินครั้งแรก รู้สึกจะในงาน ์ng-conf เห็นโชว์การทำ 3-Data Binding แต่ว่าก็ไม่ได้ลองใช้อะไรเท่าไหร่ มาวันนี้ก็เลยลองทำแอพเล่นๆ ด้วย Android ซะเลย หากใครต้องการทำแอพแนว Real Time เช่นพวกแอพแชต หรือว่าแนว Co-Work หรือเอามาทำเกมแข่งกันแบบ 1-1 ก็น่าจะได้ รู้สึกเคยเห็นตัวอย่างอยู่เหมือนกัน Firebase น่าจะเหมาะสมเลย อีกอย่าง ฟรีด้วยครับ (แต่ว่า Limit 50 Max Connections)
หมดแล้ว 30 วัน บอกตรงๆว่าเหนือ่ยมากๆ แถมนอนดึกทุกวันเลย บางวัน หลักจากเลิกงาน แทบไม่อยากเปิดคอม พอหัวถึงหมอนก็หลับเลย โอเค ถือว่า Challenge Complete แล้ว หลังจากนี้จะได้มีเวลาให้กับโปรเจ็คเกมของตัวเองซะที ไม่นานเกินรอ :D
References
- Authors
- Name
- Chai Phonbopit
- Website
- @Phonbopit