
안녕하세요! @gbgg입니다.
지난 포스팅에서는 데이터를 쓰는 작업을 진행했었는데요,
이번 포스팅에서는 입력한 데이터를 읽고 리스트뷰에 표시하는 작업을 진행하겠습니다.
제가 전문가가 아니다보니 부족한 점이나 잘못된 부분이 있을 수 있습니다. 피드백 주시면 즉시 반영하겠습니다.
실시간 데이터베이스
개발할 앱/웹 등이 정보를 제공하거나 받아와야 할 경우, 또는 데이터를 주고 받아야 할 경우 등등 데이터베이스 기능은 개발에 있어 필수라고 생각합니다. 파이어베이스에서는 다양한 백엔드 서비스를 제공하고 있는데 그 중 가장 대표적인 기능이 '실시간 데이터베이스' 입니다.
이번 포스팅에서는 이 기능을 사용하여 데이터를 불러온 뒤 실시간으로 감지하여 리스트뷰에 이 데이터들을 표시해보겠습니다.
준비물
1. Google 계정
2. Android Studio 1.5 이상
앱 개발을 위해 안드로이드 스튜디오를 설치하였습니다.
위 링크로 들어가셔서 다운받으시면 됩니다.
생성된 프로젝트 접속하기

구글 파이어베이스에 접속하면 아래와 같이 생성되어있는 프로젝트들이 표시됩니다.
지난 포스팅에서 생성했던 steemitTest - database에 접속하겠습니다.

지난 번 app을 통해 넣어주었던 데이터들이 그대로 남아있습니다.
이번 포스팅에서는 이 데이터들을 불러와 화면에 표시하는 작업을 진행할 것입니다.
우선 지난번에 했던 작업에 이어 진행해보겠습니다.
- 데이터베이스에 임의값 대신 입력한 값 전송하기
databaseReference.child("message").push().setValue('2');
지난 포스팅에서는 'message' 라는 child에 '2'값을 넣어보았습니다.
이번에는 edittext를 생성하여 입력한 값을 넣어보겠습니다.

plan text를 선택하여 화면에 배치합니다.

'Center Vertically in Parent'와 'Center Horizontally in Parent'를 눌러
화면상에서 잘 배치되도록 조절해줍니다. 버튼도 마찬가지로 진행해줍니다.

배치가 완료되었다면 코드로 넘어가 view를 연결하고 string형 변수를 선언해보겠습니다.

private EditText editdt;
public String msg;
editdt의 텍스트값을 받아 msg에 저장하겠습니다.
editdt = (EditText) findViewById(R.id.editText);
먼저 EditText를 연결한 뒤
msg = editdt.getText().toString();
databaseReference.child("message").push().setValue(msg);
위 값을 붙여넣어봅시다.

다음과 같이 완료되었다면 테스트 겸 값을 한번 보내보겠습니다.

'스팀잇 알러뷰'와 '스팀잇 짱짱맨'을 전송하였습니다.
이제 데이터를 읽어오는 작업을 진행해보겠습니다.
데이터 읽어오기
데이터는 리스트 뷰에 순차적으로 표시해보겠습니다.
아까 edittext를 생성했던 것 처럼 리스트뷰를 생성해보겠습니다.

리스트 뷰를 생성하고 리스트뷰의 id값을 'listviewmsg'로 정의해보았습니다.
이제 코드로 넘어가겠습니다.

private FirebaseDatabase mDatabase;
private DatabaseReference mReference;
private ChildEventListener mChild;
private ListView listView;
private ArrayAdapter<String> adapter;
List<Object> Array = new ArrayList<Object>();
파이어베이스 데이터값을 실시간으로 갱신하기 위해 정의해줍니다.
또한 array배열을 생성하고 리스트뷰와 연결할 ArrayAdapter도 'adapter'로 정의합니다.

listView의 뷰를 연결하고 아까 생성한 어레이어뎁터와 리스트 뷰를 연결합니다.
그리고 조금 후에 만들 initDatabase();함수를 실행시켜둡니다.
listView = (ListView) findViewById(R.id.listviewmsg);
initDatabase();
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, new ArrayList<String>());
listView.setAdapter(adapter);

- onChildAdded
- onChildChanged
- onChildRemoved
- onChildMoved
- onCancelled
이 리스너들에 대한 설명은 파이어베이스 문서에서도 찾아볼 수 있습니다.

데이터가 변경되거나 추가되거나 삭제되거나 이동되거나 실행취소되거나 등등
데이터 값이 변하는 순간에 맞춰 작업을 요청할 수 있습니다.
앞으로 작업할 때 필요하므로 미리 정의해둡니다.

파이어베이스 문서에 보면 ValueEventListener에 대한 설명이 나와있습니다.
경로 전체에 대해 변경값이 있으면 실행시키는 리스너로 이번 포스팅에서 데이터가 추가/변경되었을 경우 값을 리스트뷰에 넣을 때 쓰일 리스너입니다.
initDatabase 함수 코드
private void initDatabase() {
mDatabase = FirebaseDatabase.getInstance();
mReference = mDatabase.getReference("log");
mReference.child("log").setValue("check");
mChild = new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
};
mReference.addChildEventListener(mChild);
}
@Override
protected void onDestroy() {
super.onDestroy();
mReference.removeEventListener(mChild);
}

onCreate 함수 아래에 붙여넣으면 됩니다.
이제 ValueEventListener 리스너를 생성해 보겠습니다. 리스너 형식은 다음과 같습니다.
mReference = mDatabase.getReference("child 이름"); // 변경값을 확인할 child 이름
mReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot messageData : dataSnapshot.getChildren()) {
// child 내에 있는 데이터만큼 반복합니다.
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
이제 작업할 내용을 다음과 같이 정의해봅시다.
- 리스트뷰(어댑터)에 값을 넣기 전 초기화한다.
- child내에 있는 messageData를 String형 변수에 저장한다.
- Array배열과 리스트뷰에 해당 값을 밀어넣는다.
- 리스트뷰를 갱신한다.

가장 먼저 리스트뷰를 초기화해야 합니다. 이 작업은 child내에 있는 데이터 값을 불러오기 전에 수행되야 하므로 다음과 같이 입력하여 넣습니다.
adapter.clear();

child 내에 있는 메세지데이터를 저장하는 작업은 for문 내에 넣습니다.
String msg2 = messageData.getValue().toString();
Array.add(msg2);
adapter.add(msg2);

adapter.notifyDataSetChanged();
listView.setSelection(adapter.getCount() - 1);
리스트뷰를 갱신하고 마지막 위치를 카운트해서 보내줍니다.
결과
자! 완료되었습니다.
이제 파이어베이스의 실시간 데이터베이스에서 값이 변경되면 앱의 리스트뷰가 갱신되게 됩니다.
테스트하기 전에 파이어베이스로 접속하여 기존에 있던 데이터들을 모두 지워봅시다.

보시는 것 처럼 데이터가 모두 지워지면 해당 child도 지워지게됩니다.
다 지웠으면 앱으로 돌아가 한번 입력해보겠습니다.

핸드폰 입력화면입니다. 채팅이 입력되면 데이터베이스의 변화를 감지하여 리스트뷰에 표시해주는 것을 확인할 수 있습니다.

Firebase의 데이터베이스에는 핸드폰에서 입력했던 것과 같이 데이터가 들어가 있는 것을 확인할 수 있습니다.
Firebase 실시간 데이터베이스
이번 포스팅에서는 데이터를 전송한 뒤 그 값을 받아 리스트뷰에 표시해보았습니다.
파이어베이스에서는 이처럼 여러 리스너들을 제공하고 있으며 이를 통해 쉽게 데이터를 불러오고 써낼 수 있습니다.
@dakeshi 님께서 첫 포스팅에서 조언해 주신 것 처럼 첫 데이터 설계가 매우 중요합니다.
오늘은 'message' 라는 child를 생성해두고 값을 불러왔지만 실제로 사용하려면 각 사용자들의 정보(Token값)와 데이터들의 구조가 잘 이루어져있어야 수월하게 읽고 쓸 수 있습니다.
다음 포스팅에서는 앱을 처음 켤 때 얻는 token값으로 사용자들을 구별하여 개인설정 정보를 저장하고 읽을 수 있도록 구현해보겠습니다.
다음 포스팅에서 찾아뵙겠습니다! @gbgg
지난 포스팅
[Firebase] 1. 혁신적인 백엔드플랫폼 파이어베이스(Firebase)
[Firebase] 2. 파이어베이스(Firebase) 실시간 데이터베이스에 데이터 쓰기 (app)
으엉엉 너무 어려운 내용이지만 언젠간 다 이해하고 말거에요!
으엉엉 쉽게써보려고 했는데 능력밖인가봐요 ㅠㅠㅋㅋㅋ
흐어 아닙니당!! 제가 멍청이라 그래요 ;ㅁ; 공부하고 오겠습니다! ㅋㅋㅋㅋㅋ
읽어주신것만으로도 감사해욬ㅋㅋ 그나저나 이제 vr기기 집에 하나쯤은 두고싶은데 핸드폰끼워서 쓰는것이랑 액정이 달려있는거랑 어떤게 더 좋은가요??ㅋㅋㅋ
오! VR 기기 사시나요?!
휴대성면에서는 핸드폰이 좋은데, 퀄리티나 발열 떄문에 저는 컴퓨터와 연결해서 쓰는 VR 기기를 추천합니당 ㅠㅠㅠ 해외 배송도 괜찮으시면 전 오큘러스도 추천!
아아 그렇군여 ㅠㅠㅋㅋㅋ 혹시 오큘러스랑 오디세이랑 큰 차이점이 있나여?? 가격대가 비슷하길래요 ㅋㅋㅋ
오큘러스는 이미 플랫폼을 가지고 있어서 콘텐츠가 풍부하고, 오딧세이는 상대적으로 최근에 출시된거라 콘텐츠가 아쉽다고 들었어요 ㅠㅠㅠ 기기 자체의 퀄리티는 비슷한 것 같아요! 저희는 개발을 하고 있어서 엔진을 지원하지 않는 오딧세이는 못쓴답니다 8ㅅ8
ㅜㅡㅜ컴맹인 저로썬 뭐가 뭔지 알수가 없네요......
죄송합니다ㅜㅡㅜ흑흑
방문해주신것만으로도 너무 감사드립니다!
다른것도 많이 포스팅하겠습니다 ㅠㅠㅎㅎ
대단합니다
멋지십니다 좋은정보 잘보고 갑니다
천천히 보고 공부하고 배워야겠죠
어필하고 공유하겠 습니다^.^
감사합니다! 최대한 세세하게 풀어서 써봤는데 앞으로도 더 노력하겠습니다~
포스팅 잘 봤습니다. 제품명은 Firebase로 통일해서 표기하면 좋을 것 같습니다. 실시간데이터베이스의 데이터 입력 수정과 관련해서 JSON에서 처리가능한 데이터 타입으로 제한이 있었던 것으로 기억하는데 이부분도 언급해주시면 좋을 듯. 다음 포스팅도 기대하겠습니다. 좋은 하루 되세요~
늘 피드백주셔서 정말 많은 도움이 되고있습니다. 감사합니다 피드백주신부분은 모르고있던 부분인데 자세히 찾아보고 포스팅 올리겠습니다. 감사합니다!
관련 내용은 데이터 읽기 및 쓰기 섹션에 나와있습니다. android 데이터 타입 관련 제약사항이 언급되어 있습니다. https://firebase.google.com/docs/database/android/read-and-write
아 이부분 말씀하셨던거군요.. 감사합니다!
흥미롭네요~~
늘 찾아주셔서 감사합니다. 앞으로 더 좋은 포스팅으로 찾아뵙겠습니다.
역시나 제가 모르는 분야.ㅠ
아무튼 성심성의껏 작성하신 글이 좋습니다^^
좋게봐주셔서 감사합니다! 앞으로 더 알찬 포스팅이 되도록 노력하겠습니다 ㅎㅎ
불금이 기다립니다!
짱짱한 불금!
항상 감사합니다!^^