Membuat Aplikasi Chatting Part 6 - Percakapan Realtime
activity_chat.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ChatActivity">
<EditText
android:id="@+id/edtMessage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ems="10"
android:gravity="start|top"
android:inputType="textMultiLine"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/imbSend"
app:layout_constraintStart_toStartOf="parent" />
<ImageButton
android:id="@+id/imbSend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="@drawable/ic_baseline_send_24" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvChat"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/edtMessage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
list_message.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/clMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txtMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="4dp"
android:text=""
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private FirebaseFirestore db;
private FloatingActionButton fabAdd;
private String uid;
private RecyclerView rvFriend;
private LinearLayoutManager mLayoutManager;
private FirestoreRecyclerAdapter<Friend, FriendViewHolder> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAuth = FirebaseAuth.getInstance();
db = FirebaseFirestore.getInstance();
mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() == null) {
Intent i = new Intent(MainActivity.this,LoginActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
finish();
} else {
goMain();
}
}
};
}
private void goMain() {
FirebaseUser currentUser = mAuth.getCurrentUser();
uid = currentUser.getUid();
rvFriend = findViewById(R.id.rvFriend);
mLayoutManager = new LinearLayoutManager(this);
mLayoutManager.setReverseLayout(true);
mLayoutManager.setStackFromEnd(true);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(rvFriend.getContext(), mLayoutManager.getOrientation());
rvFriend.addItemDecoration(dividerItemDecoration);
rvFriend.setHasFixedSize(true);
rvFriend.setLayoutManager(mLayoutManager);
FirestoreRecyclerOptions<Friend> options = new FirestoreRecyclerOptions.Builder<Friend>()
.setQuery(db.collection("user").document(uid).collection("friend"),Friend.class)
.build();
adapter = new FirestoreRecyclerAdapter<Friend, FriendViewHolder>(options) {
@Override
protected void onBindViewHolder(@NonNull FriendViewHolder holder, int position, @NonNull Friend model) {
String uidFriend = getSnapshots().getSnapshot(position).getId();
holder.setList(uidFriend);
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
goChatRoom(model.getIdChatRoom(),uidFriend);
}
});
}
@NonNull
@Override
public FriendViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_friend, parent,false);
return new FriendViewHolder(view);
}
};
rvFriend.setAdapter(adapter);
adapter.startListening();
fabAdd = findViewById(R.id.fabAdd);
fabAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Dialog dialog = new Dialog(MainActivity.this);
dialog.setTitle("Enter User UID");
dialog.setContentView(R.layout.dialog_add);
dialog.show();
final EditText edtID = dialog.findViewById(R.id.edtID);
Button btnOk = dialog.findViewById(R.id.btnOk);
btnOk.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String idUser = edtID.getText().toString();
if (TextUtils.isEmpty(idUser)) {
edtID.setError("required");
} else {
db.collection("user").whereEqualTo("id",idUser)
.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
if(queryDocumentSnapshots.isEmpty()) {
edtID.setError("ID not found");
} else {
for (DocumentSnapshot documentSnapshot : queryDocumentSnapshots.getDocuments()) {
String uidFriend = documentSnapshot.getId();
if (uid.equals(uidFriend)) {
edtID.setError("wrong ID");
} else {
dialog.cancel();
checkFriendExist(uidFriend);
}
}
}
}
});
}
}
});
}
});
}
public class FriendViewHolder extends RecyclerView.ViewHolder {
View mView;
ImageView imgProfile;
TextView txtName;
public FriendViewHolder(View itemView) {
super(itemView);
mView = itemView;
imgProfile = mView.findViewById(R.id.imgProfile);
txtName = mView.findViewById(R.id.txtName);
}
public void setList(String uidFriend) {
db.collection("user").document(uidFriend).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot documentSnapshot = task.getResult();
if (documentSnapshot.exists()) {
String name = documentSnapshot.get("name",String.class);
txtName.setText(name);
}
}
}
});
}
}
private void checkFriendExist(final String uidFriend) {
db.collection("user").document(uid).collection("friend").document().get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if(task.isSuccessful()) {
DocumentSnapshot documentSnapshot = task.getResult();
if (documentSnapshot.exists()) {
String idChatRoom = documentSnapshot.get("idChatRoom", String.class);
goChatRoom(idChatRoom,uidFriend);
} else {
createNewChatRoom(uidFriend);
}
}
}
});
}
private void createNewChatRoom(final String uidFriend) {
HashMap<String,Object> dataChatRoom = new HashMap<>();
dataChatRoom.put("dateAdded", FieldValue.serverTimestamp());
db.collection("chatRoom").document(uid+uidFriend).set(dataChatRoom).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
//write user data
HashMap<String,Object> dataFriend = new HashMap<>();
dataFriend.put("idChatRoom",uid+uidFriend);
db.collection("user").document(uid).collection("friend").document(uidFriend).set(dataFriend).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
//write on user's friend data
HashMap<String,Object> dataUserFriend = new HashMap<>();
dataUserFriend.put("idChatRoom",uid+uidFriend);
db.collection("user").document(uidFriend).collection("friend").document(uid).set(dataUserFriend).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
goChatRoom(uid+uidFriend,uidFriend);
}
});
}
});
}
});
}
private void goChatRoom(String idChatRoom, String uidFriend) {
Intent i = new Intent(MainActivity.this,ChatActivity.class);
i.putExtra("idChatRoom",idChatRoom);
i.putExtra("uidFriend",uidFriend);
startActivity(i);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_logout) {
FirebaseAuth.getInstance().signOut();
Intent i = new Intent(MainActivity.this,LoginActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
finish();
} else if (id == R.id.action_profile) {
Intent i = new Intent(MainActivity.this,ProfileActivity.class);
startActivity(i);
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
@Override
protected void onStop() {
super.onStop();
mAuth.removeAuthStateListener(mAuthListener);
}
}
Chat.java
public class Chat {
private String message, uid;
private Date date;
public Chat () {}
public Chat(String message, String uid, Date date) {
this.message = message;
this.uid = uid;
this.date = date;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
ChatActivity.java
public class ChatActivity extends AppCompatActivity {
private FirebaseAuth mAuth;
private FirebaseFirestore db;
private RecyclerView rvChat;
private EditText edtMessage;
private ImageButton imbSend;
private LinearLayoutManager mLayoutManager;
FirestoreRecyclerAdapter<Chat, ChatViewHolder> adapter;
String uid,idChatroom;
String uidFriend;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
mAuth = FirebaseAuth.getInstance();
db = FirebaseFirestore.getInstance();
FirebaseUser currentUser = mAuth.getCurrentUser();
uid = currentUser.getUid();
rvChat = findViewById(R.id.rvChat);
edtMessage = findViewById(R.id.edtMessage);
imbSend = findViewById(R.id.imbSend);
idChatroom = getIntent().getExtras().getString("idChatRoom");
uidFriend = getIntent().getExtras().getString("uidFriend");
mLayoutManager = new LinearLayoutManager(this);
mLayoutManager.setReverseLayout(false);
mLayoutManager.setStackFromEnd(true);
rvChat.setHasFixedSize(true);
rvChat.setLayoutManager(mLayoutManager);
FirestoreRecyclerOptions<Chat> options = new FirestoreRecyclerOptions.Builder<Chat>()
.setQuery(db.collection("chatRoom").document(idChatroom).collection("chat").orderBy("date"), Chat.class)
.build();
adapter = new FirestoreRecyclerAdapter<Chat, ChatViewHolder>(options) {
@Override
protected void onBindViewHolder(@NonNull ChatViewHolder holder, int position, @NonNull Chat model) {
holder.setList(model.getUid(),model.getMessage(),getApplicationContext());
}
@NonNull
@Override
public ChatViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_message, parent,false);
return new ChatViewHolder(view);
}
};
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
mLayoutManager.smoothScrollToPosition(rvChat,null,adapter.getItemCount());
}
});
rvChat.setAdapter(adapter);
adapter.startListening();
imbSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String message =edtMessage.getText().toString().trim();
if (TextUtils.isEmpty(message)) {
} else {
HashMap<String,Object> dataMessage = new HashMap<>();
dataMessage.put("date", FieldValue.serverTimestamp());
dataMessage.put("message",message);
dataMessage.put("uid",uid);
db.collection("chatRoom").document(idChatroom).collection("chat").document().set(dataMessage).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
edtMessage.setText("");
}
});
}
}
});
}
public class ChatViewHolder extends RecyclerView.ViewHolder {
View mView;
ConstraintLayout clMessage;
TextView txtMessage;
public ChatViewHolder(@NonNull View itemView) {
super(itemView);
mView = itemView;
clMessage = mView.findViewById(R.id.clMessage);
txtMessage = mView.findViewById(R.id.txtMessage);
}
public void setList(String uidMessage, String message, Context context) {
if (uidMessage.equals(uid)) {
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(clMessage);
constraintSet.setHorizontalBias(R.id.txtMessage,1.0f);
constraintSet.applyTo(clMessage);
txtMessage.setBackground(ResourcesCompat.getDrawable(context.getResources(),R.drawable.bg_message,context.getTheme()));
txtMessage.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
txtMessage.setText(message);
} else {
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(clMessage);
constraintSet.setHorizontalBias(R.id.txtMessage,0.0f);
constraintSet.applyTo(clMessage);
txtMessage.setBackground(ResourcesCompat.getDrawable(context.getResources(),R.drawable.bg_message_friend,context.getTheme()));
txtMessage.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
txtMessage.setText(message);
}
}
}
}
Video tutorial
Download Source Code (link)
Comments
Post a Comment