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


Như vậy Tui đã hướng dẫn xong toàn bộ CRUD trong Realtime Database Firebase, các bạn nhớ làm theo thứ tự bài 1, bài 2, bài 3 nha.

Ở bài này Tui sẽ trình bày cách sử dụng Firebase ở mức cao hơn 1 xíu đó là: Sử dụng Java model class, Custom layout, tái sử dụng lại Realtime database ở bài trước(tức là giờ có 2 App cùng sử dụng 1 CSDL). Để giúp phần mềm được chuyên nghiệp và dễ dàng hơn cho Dev cũng như Customer.

Kết thúc bài này, ta có giao diện phần mềm như sau:

Các bước làm giống như các bài trước. Tuy nhiên trong bài này ta sẽ Bổ sung Customlayout, model class.

Tui mới update Android studio version mới nhất 3.2.1 (Tính tới ngày 15/10/2018) nên Tui new lại Project từ đầu nha.

Khởi động Android Studio:

Chọn Start a new Android Studio project:

Đặt tên Project là AdvancedRealtimeDatabaseFirebase rồi bấm Next

Chọn API 26 rồi bấm Next:

Tiếp tục chọn Empty Activity trong màn hình trên rồi bấm Next:

Mặc định để MainActivity rồi bấm Finish để tạo Project:

Đợi cho Project tạo xong ta sẽ kết nối tới Firebase bằng cách vào menu Tools/ chọn Firebase:

Sau khi chọn Firebase, lúc này công cụ trợ giúp sẽ xuất hiện:

Google cung cấp rất nhiều Service, nhưng ta cũng quan tâm tới Realtime Database-> nhấn vào mục có chữ này:

Tiếp tục nhấn vào “Save and retrieve data” để kết nối Realtime Database:

Google cũng  cung cấp nhiều bước, ta nhấn vào bước 1 “Connect to Firebase”, lúc này cửa sổ kết nối Firebase xuất hiện, tại bài Advanced này Tui muốn tái sử dụng lại CSDL ở các bài trước, Tui sẽ chọn mục số 2 “Choose an existing Firebase ỏ Google Project”:

Lúc này màn hình sẽ như sau:

rõ ràng ở trên bạn thấy “RealtimeDatabaseFirebase”, là Project ở các bài trước. Giờ ta bấm “Connect to Firebase”:

Ta chờ nó kết nối nha, nếu có lỗi xảy ra nó sẽ xuất hiện thông báo như màn hình dưới đây:

Đừng lo lắng, tiếp tục bấm lại “Connect to Firebase”, lúc này màn hình sau xuất hiện:

Ta nhấn vào “Sync” để đồng bộ, kết quả sẽ thành công như dưới đây:

Tiếp tục nhấn vào “Add the Realtime Database Rules” ở bước 2:

Chương trình sẽ yêu cầu thêm một số thư viện vào build.gradle. Ta nhấn Accept Changes:

Quan sát tập tin build.gradle, có lệnh: implementation ở cuối cùng. Ta xóa :15.0.0 đi:

Sau đó nhấn vào nút Try Again ở góc trên màn hình thông báo lỗi. Sau khi thành công thì ta bắt đầu lập trình được rồi. Lưu ý là khi kết nối thành công thì trên Firebase Console ta cũng thấy xuất hiện app này nha:

Như vậy bây giờ là 2 Ứng dụng Android có thể sử dụng chung 1 cơ sở dữ liệu Realtime Database Firebase rồi.

Ta xem lại cấu trúc JSON trên Firebase:

Bây giờ ta sẽ tạo 1 java class để mapping dữ liệu: Bằng cách nhấn chuột phải vào java/ chọn New / chọn Package:

Lúc này cửa sổ tạo package sẽ show ra như dưới đây:

Ta chọn dòng giữa rồi nhấn OK:

Đặt tên Package mới rồi nhấn OK. Lưu ý model để cuối cùng nha, sao cho nó có cấu trúc như vầy cho nó khóa học:

Tiếp tục nhấn chuột phải vào model / chọn New / chọn Java Class:

Màn hình tạo Lớp mới xuất hiện ra như bên dưới. Ta đặt tên lớp là Contact:

Nhấn OK để đồng ý tạo lớp Contact:

Chỉ sửa coding cho Lớp Contact này như dưới đây:


package com.communityuni.model;

public class Contact {
private String contactId;
private String name;
private String phone;
private String email;

public String getContactId() {
return contactId;
}

public void setContactId(String contactId) {
this.contactId = contactId;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getPhone() {
return phone;
}

public void setPhone(String phone) {
this.phone = phone;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}
}

Vì ta làm Custom Layout để hiển thị danh sách Contact như hình:

Nên ta cần tạo 1 layout như sau:

Bấm chuột phải vào layout/ chọn New / chọn Layout resource file:

Đặt tên file là item rồi bấm OK:

Sau khi bấm OK, ta có giao diện:

Chỉnh sửa layout của item.xml sao cho giao diện đáp ứng yêu cầu:

Dưới đây là file XML layout của item.xml:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:id="@+id/txtId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView"
android:textColor="@android:color/holo_red_dark"
android:textSize="25sp" />

<TextView
android:id="@+id/txtName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView"
android:textColor="?android:attr/colorActivatedHighlight"
android:textSize="25sp" />

<TextView
android:id="@+id/txtEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView"
android:textColor="@android:color/holo_green_dark"
android:textSize="25sp" />

<TextView
android:id="@+id/txtPhone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView"
android:textColor="@android:color/holo_blue_dark"
android:textSize="25sp" />

<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="3dp"
android:background="?attr/colorControlActivated" />
</LinearLayout>

Tiếp tục lặp lại bước tạo package mới, đó là package adapter:

Bấm chuột phải vào java/ chọn New/ chọn Package:

Chọn mục số 2:

Nhấn OK để đặt tên cho Package:

package adapter cũng đồng cấp với package model:

Tiếp tục tạo một lớp tên là : ContactAdapter để vẽ giao diện theo Custom Layout

Bấm chuột phải vào thư mục adapter/ chọn New/ chọn Java Class:

Đặt tên cho Class là ContactAdapter:

Sau đó nhấn OK để đồng ý tạo class, chỉnh sửa coding cho ContactAdapter như dưới đây:


package com.communityuni.adapter;

import android.app.Activity;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import com.communityuni.advancedrealtimedatabasefirebase.R;
import com.communityuni.model.Contact;

public class ContactAdapter extends ArrayAdapter<Contact> {
Activity context;
int resource;
public ContactAdapter(Activity context, int resource) {
super(context, resource);
this.context=context;
this.resource=resource;
}

@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View custom=context.getLayoutInflater().inflate(resource,null);
TextView txtId=custom.findViewById(R.id.txtId);
TextView txtName=custom.findViewById(R.id.txtName);
TextView txtPhone=custom.findViewById(R.id.txtPhone);
TextView txtEmail=custom.findViewById(R.id.txtEmail);
Contact contact=getItem(position);
txtId.setText(contact.getContactId());
txtName.setText(contact.getName());
txtPhone.setText(contact.getPhone());
txtEmail.setText(contact.getEmail());
return custom;
}
}

 

OK, cũng sắp xong rồi. Bây giờ bạn quay lại MainActivity để coding:


package com.communityuni.advancedrealtimedatabasefirebase;

import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;

import com.communityuni.adapter.ContactAdapter;
import com.communityuni.model.Contact;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

public class MainActivity extends AppCompatActivity {

ListView lvContact;
ContactAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addControls();
getContactsFromFirebase();
}
private void getContactsFromFirebase() {
FirebaseDatabase firebaseDatabase=FirebaseDatabase.getInstance();
DatabaseReference myRef= firebaseDatabase.getReference("contacts");
adapter.clear();
myRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dss : dataSnapshot.getChildren())
{
//convert ra đối tượng Contact:
Contact contact=dss.getValue(Contact.class);
String key=dss.getKey();
contact.setContactId(key);
adapter.add(contact);
}
}

@Override
public void onCancelled(@NonNull DatabaseError databaseError) {

}
});
}

private void addControls() {
lvContact=findViewById(R.id.lvContact);
adapter=new ContactAdapter(this,R.layout.item);
lvContact.setAdapter(adapter);
}
}

ở trên ta thấy dòng lệnh 37:

Contact contact=dss.getValue(Contact.class);

Dòng lệnh này để đưa dữ liệu trong HashMap về đúng kiểu Contact (nó tự mapping)

Khi có đối tượng contact rồi thì ta dán nó vào adapter là tự nhiên có giao diện như mong muốn

Chạy phần mềm lên ta sẽ có kết quả như sau:

Như vậy Tui đã hướng dẫn xong cách dùng model class, customlayout để truy suất dữ liệu từ Firebase. Cách làm cũng tương tự như loại cơ bản. tuy nhiên cách này sẽ khoa học hơn, tùy biến nhanh hơn.

Ngoài ra các thao tác Thêm, Sửa, Xóa. Các bạn có thể cho chương trình lắng nghe kết quả trả về, tương tự như:

Ví dụ: Thêm sự kiện xóa Contact khi nhấn lâu vào ListView và kiểm tra kết quả thành công hay thất bại:


protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addControls();
getContactsFromFirebase();
addEvents();
}
private void addEvents() {

lvContact.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Contact contact=adapter.getItem(position);
FirebaseDatabase firebaseDatabase=FirebaseDatabase.getInstance();
DatabaseReference myRef= firebaseDatabase.getReference("contacts");
myRef.child(contact.getContactId()).removeValue()
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Toast.makeText(MainActivity.this,"Thành công",Toast.LENGTH_LONG).show();

adapter.remove(contact);
}})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(MainActivity.this,"Lỗi rồi :"+ e.toString(),Toast.LENGTH_LONG).show();
}
});
return false;
}
});
}

Xử lý cho Thêm Contact tương tự nha!

Đây là sourcode của chương trình: Tải ở đây

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

3 responses

  1. Hi thầy Thanh, thầy có thể làm 1 bài demo về lưu trữ dữ liệu dạng object lên Firebase nhưng có cả ảnh được không ạ? Em cảm ơn thầy đã đăng các bài học rất chi tiết ạ.

  2. […] Phần Cloud Storage Tui sẽ có những TUT hướng dẫn riêng. Còn trong bài này Tui vẫn dùng dự án từ bài số 4, tiếp tục hiệu chỉnh phần mềm để thêm các chức năng: CHỤP HÌNH + CHỌN […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: