Phát triển ứng dụng cơ sở dữ liệu thời gian thực với Firebase-phần 2

phần 1 Tui đã hướng dẫn các bạn cách thức kết nối Android Studio tới Realtime Database Firebase,  cách thao tác Cơ sở dữ liệu trên console.firebase.google.com cũng như cách thức truy suất danh sách Contact từ Realtime Database Firebase xuống Client.

Ở bài này Tui sẽ hướng dẫn các bạn cách thức thêm mới dữ liệu từ Android lên Realtime Database. Tuy nhiên Tui vẫn sử dụng cách thức cơ bản nhất, khi nào qua hết tất cả các bài cơ bản, Tui sẽ trình bày phần nâng cao đó là sử dụng Model class, Transaction…. Còn những bài này chỉ cần các bạn hiểu cơ chế hoạt động, cách thức gọi lệnh là đủ rồi.

Tiếp tục mở lại Project đã được hướng dẫn trong phần 1.

Bổ sung Option Menu có 1 MenuItem là “Thêm Contact”  như hình dưới đây:

Để them Menu ta làm như sau:

Bấm chuột phải vào thư mục res/ chọn new/ chọn Directory:

Sau khi chọn Director, Android Studio sẽ cung cấp 1 màn hình yêu cầu ta đặt tên, Ta sẽ đặt tên Directory là: menu như hình trong màn hình dưới đây:

Đặt tên xong bấm OK, ta thấy thư mục menu được tạo vào Project:

Tiếp tục bấm chuột phải vào menu/ chọn New/ chọn menu resource file:

Android Studio sẽ cung cấp màn hình cho ta đặt tên menu cũng như các thông số cấu hình khác:

Để đơn giản, ta chỉ quan tâm tới phần File Name, đặt tên là : main_menu rồi bấm OK:

Ta tiến hành kéo Menu Item ra, đổi nhãn thành Thêm Contact, đặt id là mnuAdd.

đây là main_menu.xml:

[code language=”xml”]

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/mnuAdd"
android:title="Thêm Contact" />
</menu>

[/code]

Trong coding của màn hình MainActivity, Ta Override hàm onCreateOptionsMenu ra để tạo Menu cho Activity:

Chỉ cần gõ onCreate thì Android Studio cũng gợi ý ra hàm onCreateOptionsMenu, ta chỉ cần Enter là nó xổ hết ra cho lẹ:

Sau đó ta tiến hành cập nhật Coding như dưới đây:

[code language=”java”]

@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater=getMenuInflater();
menuInflater.inflate(R.menu.main_menu,menu);
return super.onCreateOptionsMenu(menu);
}

[/code]

Tiếp tục bổ sung hàm xử lý người dùng lựa chọn MenuItem – onOptionsItemSelected, ta cũng chi cần gõ 1 vài ký tự đầu onOption… nó tự xổ ra và ta chọn cho lẹ:

Ta sẽ có coding như sau:

[code language=”java”]

@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId()==R.id.mnuAdd) // kiểm tra người dùng chọn Menu Thêm Contact
{
//mở màn hình thêm ở đây (sẽ gọi sau)
}
return super.onOptionsItemSelected(item);
}

[/code]

Giờ Ta thêm một màn hình mới để nhập liệu cho Contact: Bấm chuột phải vào Package/ chọn New/ chọn Activity/ chọn Empty Activity :

Màn hình tạo Activity hiển thị ra, ta tiến hành đặt tên cho màn hình:

Ở trên ta đặt: là ThemContactActivity rồi bấm Finish
Tiến hành thiết kế giao diện cho màn hình Thêm mới:

XML Layout của activity_them_contact.xml như sau:

[code language=”xml”]

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ThemContactActivity">
<TextView
android:id="@+id/textView0"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Nhập Contact Id:"
android:textSize="25sp" />

<EditText
android:id="@+id/edtContactId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Contact Id ở đây"
android:inputType="textPersonName"
android:textSize="25sp" />
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Nhập Ten:"
android:textSize="25sp" />

<EditText
android:id="@+id/edtTen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Tên ở đây"
android:inputType="textPersonName"
android:textSize="25sp" />
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Nhập Email:"
android:textSize="25sp" />

<EditText
android:id="@+id/edtEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Email ở đây"
android:inputType="textEmailAddress"
android:textSize="25sp" />
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Nhập Phone:"
android:textSize="25sp" />

<EditText
android:id="@+id/edtPhone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Phone ở đây"
android:inputType="phone"
android:textSize="25sp" />

<Button
android:onClick="xuLyThemMoi"
android:id="@+id/btnDongYThem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Đồng Ý Thêm"
android:textSize="25sp" />

</LinearLayout>

[/code]

Để có thể lưu một dữ liệu mới từ Client lên Database Firebase thì không mấy khó khăn, do Google cung cấp cho ta phương thức đơn giản là: setValue(dữ_liệu). Nếu chưa tồn tại Name trên Firebase thì nó tự thêm mới, nếu Name đã tồn tại thì trở thành cập nhật. Một số loại dữ liệu mà Firebase hỗ trợ đó là:

  • String
  • Long
  • Double
    Boolean
  • Map<String, Object>
  • List<Object>

Object có thể là Java Object, ta đẩy luôn 1 đối tượng hoặc danh sách đối tượng lên Server Firebase được luôn nha (Sẽ trình bày chi tiết ở những bài sau).

Cái khó của phần này chắc chỉ là do ta mapping sai giữa cấu trúc JSON trên Realtime Database Firebase với các biến truyền vào trong Android mà thôi.

Chúng ta xem cái hình Tui chụp dưới này:

Hình trên là bộ 3: Giao diện tương tác – Coding – Reatime Database Firebase

Các bạn nhìn kỹ các mũi tên mà Tui  trỏ nha. Cấu trúc Cơ sở dữ liệu (JSON) trong Firebase như thế nào thì bạn phải truyền cho đúng nha.

Ở trên cấu trúc JSON ta có:

1 element contacts . Trong thẻ contacts  có rất nhiều element con contactX, Mỗi element con này lại có 3 Element con là: email, name, phone. Trong coding ta phải so khớp chính xác với các thành phần này nha. So Khớp chính xác thì tự nhiên dữ liệu sẽ được lưu thành công, và phía mobile client bất kỳ sẽ tự động cập nhật khi có dữ liệu thay đổi (Realtime)

Chi tiết Coding cho màn hình ThemContactActivity:

[code language=”java”]

package com.communityuni.realtimedatabasefirebase;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

public class ThemContactActivity extends AppCompatActivity {
EditText edtId,edtTen,edtPhone,edtEmail;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_them_contact);
addControls();
}
private void addControls() {
edtId=findViewById(R.id.edtContactId);
edtTen=findViewById(R.id.edtTen);
edtPhone=findViewById(R.id.edtPhone);
edtEmail=findViewById(R.id.edtEmail);
}

public void xuLyThemMoi(View view) {
try {
FirebaseDatabase database = FirebaseDatabase.getInstance();
//Kết nối tới node có tên là contacts (node này do ta định nghĩa trong CSDL Firebase)
DatabaseReference myRef = database.getReference("contacts");
String contactId=edtId.getText().toString();
String ten = edtTen.getText().toString();
String phone = edtPhone.getText().toString();
String email = edtEmail.getText().toString();
myRef.child(contactId).child("phone").setValue(phone);
myRef.child(contactId).child("email").setValue(email);
myRef.child(contactId).child("name").setValue(ten);
finish();
}
catch (Exception ex)
{
Toast.makeText(this,"Error:"+ex.toString(),Toast.LENGTH_LONG).show();
}
}
}

[/code]

Cuối cùng chỉnh sửa sự kiện nhấn MenuItem trong màn hình MainActivity:

[code language=”java”]

@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId()==R.id.mnuAdd)
{
//mở màn hình thêm ở đây
Intent intent=new Intent(MainActivity.this,ThemContactActivity.class);
startActivity(intent);
}
return super.onOptionsItemSelected(item);
}

[/code]

Chạy lên Ta sẽ có kết quả như mong muốn: bất kỳ 1 Thiết bị nào thêm mới 1 Contact –> nó Sẽ được lưu trên RealTime Database Firebase –> Tất cả các thiết bị khác sẽ tự động cập nhật mới khi có dữ liệu thay đổi.

Đây là Coding đầy đủ của phần này: Link tải tại đây

Phần sau Tui sẽ trình bày cách Chỉnh sửa và Xóa dữ liệu khỏi RealTime Database Firebase cũng như lắng nghe kết quả thay công hay thất bại.

Chúc các bạn thành công.