[Firebase] 3. 파이어베이스(Firebase) 실시간 데이터베이스 불러오기, 리스트에 내용 표시하기
안녕하세요! @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
Vr은 콘텐츠가 생명이니 이왕 살거면 오큘러스사는게 좋겠네요!ㅎㅎ vr기기는 직접 가져본적이없어서 궁금한점이 많네요ㅋㅋㅋ 전문가시니까 궁금한거 있으면 또 여쭤볼게요!
ㅜㅡㅜ컴맹인 저로썬 뭐가 뭔지 알수가 없네요......
죄송합니다ㅜㅡㅜ흑흑
방문해주신것만으로도 너무 감사드립니다!
다른것도 많이 포스팅하겠습니다 ㅠㅠㅎㅎ
대단합니다
멋지십니다 좋은정보 잘보고 갑니다
천천히 보고 공부하고 배워야겠죠
어필하고 공유하겠 습니다^.^
감사합니다! 최대한 세세하게 풀어서 써봤는데 앞으로도 더 노력하겠습니다~
포스팅 잘 봤습니다. 제품명은 Firebase로 통일해서 표기하면 좋을 것 같습니다. 실시간데이터베이스의 데이터 입력 수정과 관련해서 JSON에서 처리가능한 데이터 타입으로 제한이 있었던 것으로 기억하는데 이부분도 언급해주시면 좋을 듯. 다음 포스팅도 기대하겠습니다. 좋은 하루 되세요~
늘 피드백주셔서 정말 많은 도움이 되고있습니다. 감사합니다 피드백주신부분은 모르고있던 부분인데 자세히 찾아보고 포스팅 올리겠습니다. 감사합니다!
관련 내용은 데이터 읽기 및 쓰기 섹션에 나와있습니다. android 데이터 타입 관련 제약사항이 언급되어 있습니다. https://firebase.google.com/docs/database/android/read-and-write
아 이부분 말씀하셨던거군요.. 감사합니다!
흥미롭네요~~
늘 찾아주셔서 감사합니다. 앞으로 더 좋은 포스팅으로 찾아뵙겠습니다.
역시나 제가 모르는 분야.ㅠ
아무튼 성심성의껏 작성하신 글이 좋습니다^^
좋게봐주셔서 감사합니다! 앞으로 더 알찬 포스팅이 되도록 노력하겠습니다 ㅎㅎ
불금이 기다립니다!
짱짱한 불금!
항상 감사합니다!^^