Firebase - Android Codelab (4): Read messages

Firebase Android Codelab 에서 제공하는 튜토리얼을 한국어로 정리/요약 한 것.

메시지 읽기

채팅 메시지를 포함하고 있는 Codelab 샘플 앱에 포함되 있는 initial_messages.json 파일을 파이어베이스 데이터베이스로 가져와온다.

메시지 가져오기

  1. 파이어베이스 콘솔에서 Database를 실행해 Realtime Database로 들어간다.

  2. 마우스 오른쪽 클릭으로 Import JSON을 실행한다.

{:width=”500”}

initial_messages.json 파일을 선택한다.

{:width=”500”}

  1. 메시지는 아래 같은 구조를 가지고 있다.

{:width=”500”}

실시간 데이터베이스와 스토리지 의존성 추가

앱 프로젝트의 모듈 build.gradle 에 다음 의존성을 추가

1
2
implementation 'com.google.firebase:firebase-database:15.0.0'
implementation 'com.google.firebase:firebase-storage:15.0.0'

메시지 동기화

파이어베이스 데이터베이스를 초기화 하고 데이터의 변경을 감지하는 핸들에 리스너를 추가해 준면 리사이클러 뷰에 메시지가 표시된다.

MainActivity.java 에 선언를 한다.

1
2
3
// Firebase instance variables
private DatabaseReference mFirebaseDatabaseReference;
private FirebaseRecyclerAdapter<FriendlyMessage, MessageViewHolder> mFirebaseAdapter;

MainActivity.java 의 onCreate() 에서 mProgressBar.setVisibility(ProgressBar.INVISIBLE); 를 아래 코드로 대체한다.
이 코드는 초기 있는 메시지를 추가하고 파이어베이스 데이터베이스에서 새 메시지를 대기한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// New child entries
mFirebaseDatabaseReference = FirebaseDatabase.getInstance().getReference();
SnapshotParser<FriendlyMessage> parser = new SnapshotParser<FriendlyMessage>() {
@Override
public FriendlyMessage parseSnapshot(DataSnapshot dataSnapshot) {
FriendlyMessage friendlyMessage = dataSnapshot.getValue(FriendlyMessage.class);
if (friendlyMessage != null) {
friendlyMessage.setId(dataSnapshot.getKey());
}
return friendlyMessage;
}
};

DatabaseReference messagesRef = mFirebaseDatabaseReference.child(MESSAGES_CHILD);
FirebaseRecyclerOptions<FriendlyMessage> options =
new FirebaseRecyclerOptions.Builder<FriendlyMessage>()
.setQuery(messagesRef, parser)
.build();
mFirebaseAdapter = new FirebaseRecyclerAdapter<FriendlyMessage, MessageViewHolder>(options) {
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
return new MessageViewHolder(inflater.inflate(R.layout.item_message, viewGroup, false));
}

@Override
protected void onBindViewHolder(final MessageViewHolder viewHolder,
int position,
FriendlyMessage friendlyMessage) {
mProgressBar.setVisibility(ProgressBar.INVISIBLE);
if (friendlyMessage.getText() != null) {
viewHolder.messageTextView.setText(friendlyMessage.getText());
viewHolder.messageTextView.setVisibility(TextView.VISIBLE);
viewHolder.messageImageView.setVisibility(ImageView.GONE);
} else {
String imageUrl = friendlyMessage.getImageUrl();
if (imageUrl.startsWith("gs://")) {
StorageReference storageReference = FirebaseStorage.getInstance()
.getReferenceFromUrl(imageUrl);
storageReference.getDownloadUrl().addOnCompleteListener(
new OnCompleteListener<Uri>() {
@Override
public void onComplete(@NonNull Task<Uri> task) {
if (task.isSuccessful()) {
String downloadUrl = task.getResult().toString();
Glide.with(viewHolder.messageImageView.getContext())
.load(downloadUrl)
.into(viewHolder.messageImageView);
} else {
Log.w(TAG, "Getting download url was not successful.",
task.getException());
}
}
});
} else {
Glide.with(viewHolder.messageImageView.getContext())
.load(friendlyMessage.getImageUrl())
.into(viewHolder.messageImageView);
}
viewHolder.messageImageView.setVisibility(ImageView.VISIBLE);
viewHolder.messageTextView.setVisibility(TextView.GONE);
}


viewHolder.messengerTextView.setText(friendlyMessage.getName());
if (friendlyMessage.getPhotoUrl() == null) {
viewHolder.messengerImageView.setImageDrawable(ContextCompat.getDrawable(MainActivity.this,
R.drawable.ic_account_circle_black_36dp));
} else {
Glide.with(MainActivity.this)
.load(friendlyMessage.getPhotoUrl())
.into(viewHolder.messengerImageView);
}

}
};

mFirebaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
int friendlyMessageCount = mFirebaseAdapter.getItemCount();
int lastVisiblePosition =
mLinearLayoutManager.findLastCompletelyVisibleItemPosition();
// If the recycler view is initially being loaded or the
// user is at the bottom of the list, scroll to the bottom
// of the list to show the newly added message.
if (lastVisiblePosition == -1 ||
(positionStart >= (friendlyMessageCount - 1) &&
lastVisiblePosition == (positionStart - 1))) {
mMessageRecyclerView.scrollToPosition(positionStart);
}
}
});

mMessageRecyclerView.setAdapter(mFirebaseAdapter);

이어서 파이어베이스 데이터베이스에서 갱신하기 위해서 onPause()onResume() 메서드를 갱신한다.

MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
@Override
public void onPause() {
mFirebaseAdapter.stopListening();
super.onPause();
}

@Override
public void onResume() {
super.onResume();
mFirebaseAdapter.startListening();
}

Test message sync

파이어베이스 데이터베이스에 새 메시지를 추가해서 클라이언트와 동기화가 되는지 확인해 보자,

  1. 앱을 시작하자,
  2. 파이어베이스 콘솔의 데이터베이스에서 새 메시지를 넣자,

{:width=”500”}

  1. 앱에서 추가된 메시지가 확인된다.

참조

첫 페이지

Author

Gangtai Goh

Posted on

2018-05-01

Updated on

2023-01-19

Licensed under

댓글