🙋‍♀️ Android

[Android] Firebase Realtime Database 리스트뷰에 실시간 출력하기

수댕ʕت̫͡ʔ 2023. 5. 23. 13:49

1. 구현한 기능

- Firebase RealTime Database에 저장되어있는 데이터 (전화번호, timestamp)를 안드로이드 리스트뷰에 출력

- Database가 업데이트(수정, 삭제, 추가)되면 실시간으로 안드로이드 리스트뷰에 업데이트

 

2. 결과 화면

실행화면

3. 코드

<activity_main.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"
    android:padding="16dp"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

<MainActivity.java>

package com.example.admin_manager;

import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.google.firebase.database.ChildEventListener;
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;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private ListView listView;
    private ArrayAdapter<String> adapter; //리스트뷰와 데이터 연결하는 어댑터 객체
    private List<String> userList;

    private DatabaseReference mDatabase;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listView = findViewById(R.id.listView);
        userList = new ArrayList<>();
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, userList);
        listView.setAdapter(adapter);

        mDatabase = FirebaseDatabase.getInstance().getReference().child("users"); // users경로 접근

        ValueEventListener valueEventListener = new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                userList.clear(); // 기존 리스트 초기화

                for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
                    user newUser = childSnapshot.getValue(user.class);
                    if (newUser != null) {
                        String userNumber = newUser.getUserNumber();
                        String timestamp = newUser.getTimestamp();
                        String userInfo = "사용자: " + "0" + userNumber + "\n출입시간: " + timestamp;
                        userList.add(userInfo);
                    }
                }

                adapter.notifyDataSetChanged(); // 리스트뷰 갱신
            }
            // db에서 데이터를 읽어올때 예외 발생하면 처리
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                Log.e("Firebase", "Failed to retrieve users: " + databaseError.getMessage());
            }
        };

        mDatabase.addValueEventListener(valueEventListener);
    }
}

<MainActivity.java>

package com.example.admin_manager;

import java.text.SimpleDateFormat;
import java.util.Date;

public class user {
    private String userID;
    private String userNumber;
    private String timestamp;

    public user() {
        // 기본 생성자는 Firebase에서 데이터를 가져올 때 사용됨.
    }

    public user(String userNumber) {
        this.userNumber = userNumber;
        this.timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }

    public String getUserID() {
        return userID;
    }

    public void setUserID(String userID) {
        this.userID = userID;
    }

    public String getUserNumber() {
        return userNumber;
    }

    public void setUserNumber(String userNumber) {
        this.userNumber = userNumber;
    }

    public String getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }

    @Override
    public String toString() {
        return "User{" +
                "userID='" + userID + '\'' +
                ", userNumber='" + userNumber + '\'' +
                ", timestamp='" + timestamp + '\'' +
                '}';
    }
}

4. 코드 설명

4-1.

- listview와 데이터를 연결하는 adapter 객체 생성

 private ArrayAdapter<String> adapter;

4-2. 

- valueEventListener() : 데이터 변경을 감지하고 처리 , 실시간 업데이트 

- onDataChange() : db의 데이터가 변경되었을때 호출하는 메소드, DataSnaphot 객체를 이용해 데이터를 읽어옴

- onCancellde() : 데이터 읽어오는 과정에서 예외가 발생되었을때 호출

        ValueEventListener valueEventListener = new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                userList.clear(); 

                for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
                    user newUser = childSnapshot.getValue(user.class);
                    if (newUser != null) {
                        String userNumber = newUser.getUserNumber();
                        String timestamp = newUser.getTimestamp();
                        String userInfo = "사용자: " + "0" + userNumber + "\n출입시간: " + timestamp;
                        userList.add(userInfo);
                    }
                }

                adapter.notifyDataSetChanged(); 
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                Log.e("Firebase", "Failed to retrieve users: " + databaseError.getMessage());
            }
        };

 

5. 배운점

데이터를 리스트뷰에 실시간으로 업데이트하는 구현하는 과정에 어려움이 있었다. ValueEventListener()의 기능을 알게되었고 성공적으로 원하는 기능을 구현할 수 있었다.