I cannot get the chats to display in the recycler adapter, I have already in firebase database and as well have attached firebase recycler adapter
I have tried some of the ways of getting the recycler adapter to display the chats but unable to display my adapter
private void DisplayReceiverInformation() {
receiverName.setText(messageReceiverName);
rootReference.child("Users").child(messageReceiverID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
//retrieve from db
final String userName = dataSnapshot.child("fullName").getValue().toString();
final String profileImage = dataSnapshot.child("profileImage").getValue().toString();
//set values
receiverName.setText(userName);
Picasso.get().load(profileImage).placeholder(R.drawable.profile_image_placeholder).into(receiverProfileImage);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
\\\
//initialize the above variables
private void InitializeFields() {
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//connect chat custom bar to chat activity
ActionBar actionBar = getSupportActionBar();
Objects.requireNonNull(actionBar).setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowCustomEnabled(true);
LayoutInflater layoutInflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View action_bar_view = layoutInflater.inflate(R.layout.chat_custom_toolbar, null);
actionBar.setCustomView(action_bar_view);
receiverName = findViewById(R.id.custom_profile_name);
receiverProfileImage = findViewById(R.id.custom_profile_image);
sendMessageButton = findViewById(R.id.send_message_button);
userMessageInput = findViewById(R.id.input_message);
// messageAdapter = new MessagesAdapter(ChatActivity.this,)
messageAdapter = new MessagesAdapter( messageList);
userMessagesList = (RecyclerView) findViewById(R.id.messages_list_of_users);
linearLayoutManager = new LinearLayoutManager(this);
userMessagesList.setHasFixedSize(true);
userMessagesList.setLayoutManager(linearLayoutManager);
userMessagesList.setAdapter(messageAdapter);
}
\\\
#Override
protected void onStart() {
super.onStart();
rootReference.child("Messages").child(messageSenderID).child(messageReceiverID)
.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Messages messages = dataSnapshot.getValue(Messages.class);
messageList.add(messages);
messageAdapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
\\\
MessagesAdapter.java
package com.MwandoJrTechnologies.the_smart_parent.Chats;
public class MessagesAdapter extends RecyclerView.Adapter<MessagesAdapter.MessageViewHolder> {
private List<Messages> userMessagesList;
private FirebaseAuth mAuth;
private DatabaseReference usersDatabaseReference;
public MessagesAdapter(List<Messages> userMessagesList) {
this.userMessagesList = userMessagesList;
}
public class MessageViewHolder extends RecyclerView.ViewHolder {
public TextView senderMessageText;
public TextView receiverMessageText;
public CircleImageView receiverProfileImage;
public MessageViewHolder(#NonNull View itemView) {
super(itemView);
senderMessageText = (TextView) itemView.findViewById(R.id.sender_message_text_view);
receiverMessageText = (TextView) itemView.findViewById(R.id.receiver_message_text_view);
receiverProfileImage = (CircleImageView) itemView.findViewById(R.id.receiver_message_profile_image);
}
}
#NonNull
#Override
public MessageViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.message_layout_of_users, parent, false);
mAuth = FirebaseAuth.getInstance();
return new MessageViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MessageViewHolder holder, int position) {
//get senders ID
String messageSenderID = mAuth.getCurrentUser().getUid();
Messages messages = userMessagesList.get(position);
//get ID of the receiver
String fromUserID = messages.getFrom();
//now get type of message whether text or image
String fromMessageType = messages.getType();
//retrieve receivers profile image
usersDatabaseReference = FirebaseDatabase.getInstance().getReference().child("Users").child(fromUserID);
usersDatabaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild("profileImage")){
String receiverImage = dataSnapshot.child("profileImage").getValue().toString();
Picasso.get().load(receiverImage).placeholder(R.drawable.profile_image_placeholder)
.into(holder.receiverProfileImage);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
if (fromMessageType.equals("text")){
holder.receiverMessageText.setVisibility(View.INVISIBLE);
holder.receiverProfileImage.setVisibility(View.INVISIBLE);
//display the message to the sender and to the receiver
//for the receiver
if (fromUserID.equals(messageSenderID)) {
holder.senderMessageText.setBackgroundResource(R.drawable.sender_text_message_background);
holder.senderMessageText.setTextColor(Color.WHITE);
holder.senderMessageText.setGravity(Gravity.LEFT);
holder.senderMessageText.setText(messages.getMessage());
//for receiver
} else {
holder.senderMessageText.setVisibility(View.INVISIBLE);
holder.receiverMessageText.setVisibility(View.VISIBLE);
holder.receiverProfileImage.setVisibility(View.VISIBLE);
holder.receiverMessageText.setBackgroundResource(R.drawable.receiver_text_message_background);
holder.receiverMessageText.setTextColor(Color.WHITE);
holder.receiverMessageText.setGravity(Gravity.LEFT);
holder.receiverMessageText.setText(messages.getMessage());
}
}
}
#Override
public int getItemCount() {
return userMessagesList.size();
}
}
/// my modal class
Messages.java
package com.MwandoJrTechnologies.the_smart_parent.Chats;
//modal class to retrieve messages
public class Messages {
public String date, time, type, message, from;
public Messages(){
//empty default constructor
}
//generate constructor with parameters
public Messages(String date, String time, String type, String message, String from) {
this.date = date;
this.time = time;
this.type = type;
this.message = message;
this.from = from;
}
//generate getter and setter
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
}
The above code does not give me any result in the FirebaseRecycler adapter yet I expect it to display in the FirebaseRecycler adapter
I think the answer is below.
private void DisplayReceiverInformation() {
receiverName.setText(messageReceiverName);
rootReference.child("Users").child(messageReceiverID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
//retrieve from db
final String userName = dataSnapshot.child("fullName").getValue().toString();
final String profileImage = dataSnapshot.child("profileImage").getValue().toString();
//set values
receiverName.setText(userName);
Picasso.get().load(profileImage).placeholder(R.drawable.profile_image_placeholder).into(receiverProfileImage);
messageAdapter = new MessagesAdapter( messageList);
userMessagesList = (RecyclerView) findViewById(R.id.messages_list_of_users);
linearLayoutManager = new LinearLayoutManager(this);
userMessagesList.setHasFixedSize(true);
userMessagesList.setLayoutManager(linearLayoutManager);
userMessagesList.setAdapter(messageAdapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
//here the data will be null so you must display data inside onDataChange() method.
}
Related
This is a list of qna in the firebase. I want to print this out.
But my output list doesn't show anything.
https://i.stack.imgur.com/6ctRB.png
QNA Activity
public class QnaActivity extends AppCompatActivity {
private RecyclerView qnaRv;
private ArrayList<ModelQna> qnaList;
private AdapterQna adapterQna;
private ImageButton writeBtn;
private ImageButton backbtn;
private TextView tabQnaTv;
private RelativeLayout QnaRl;
private FirebaseAuth firebaseAuth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qna);
getSupportActionBar().hide();
qnaRv = findViewById(R.id.qnaRv);
tabQnaTv = findViewById(R.id.tabQnaTv);
QnaRl = findViewById(R.id.QnaRl);
backbtn = findViewById(R.id.backBtn);
writeBtn = findViewById(R.id.writeBtn);
firebaseAuth = FirebaseAuth.getInstance();
loadAllQna();
showQnaUI();
backbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onBackPressed();
}
});
writeBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), AddQnaActivity.class);
startActivity(intent);
}
});
tabQnaTv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//load products
}
});
}
private void loadAllQna() {
qnaList = new ArrayList<>();
adapterQna = new AdapterQna(this, qnaList);
qnaRv.setAdapter(adapterQna);
//get all products
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Employees");
reference.child(firebaseAuth.getUid()).child("Qna").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
//before getting reset List
qnaList.clear();
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
ModelQna modelQna = dataSnapshot.getValue(ModelQna.class);
qnaList.add(modelQna);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseerror) {
}
});
}
private void showQnaUI() {
//show orders ui and hide products ui
QnaRl.setVisibility(View.GONE);
}
}
Model
public class ModelFaq {
private String faqId,faqTitle,faqContent, timestamp,uid,faqCategory;
public ModelFaq() {
}
public ModelFaq(String faqId, String faqTitle, String faqContent, String timestamp, String uid, String faqCategory) {
this.faqId = faqId;
this.faqTitle = faqTitle;
this.faqContent = faqContent;
this.timestamp = timestamp;
this.uid = uid;
this.faqCategory = faqCategory;
}
public String getFaqId() {
return faqId;
}
public void setFaqId(String faqId) {
this.faqId = faqId;
}
public String getFaqTitle() {
return faqTitle;
}
public void setFaqTitle(String faqTitle) {
this.faqTitle = faqTitle;
}
public String getFaqContent() {
return faqContent;
}
public void setFaqContent(String faqContent) {
this.faqContent = faqContent;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getFaqCategory() {
return faqCategory;
}
public void setFaqCategory(String faqCategory) {
this.faqCategory = faqCategory;
}
}
Qna Adapter
public class AdapterQna extends RecyclerView.Adapter<AdapterQna.HolderQna> {
private Context context;
public ArrayList<ModelQna> qnaList;
public AdapterQna(Context context, ArrayList<ModelQna> qnaList) {
this.context = context ;
this.qnaList = qnaList ;
}
#NonNull
#Override
public HolderQna onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//inflate layout
View view = LayoutInflater.from(context).inflate(R.layout.qna_item, parent, false);
return new HolderQna(view);
}
#Override
public void onBindViewHolder(#NonNull HolderQna holder, int position) {
ModelQna modelQna = qnaList.get(position);
String id = modelQna.getQnaId();
String uid = modelQna.getUid();
String qnaContent = modelQna.getQnaContent();
String qnaTitle = modelQna.getQnaTitle();
String timestamp = modelQna.getTimestamp();
//set data
holder.titleTextView.setText(qnaTitle);
holder.ContentTextView.setText(qnaContent);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//handle item clicks, show item details
}
});
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//handle item clicks, show item details
}
});
}
#Override
public int getItemCount() {
return qnaList.size();
}
class HolderQna extends RecyclerView.ViewHolder{
/*holds views of recyclerview*/
private TextView titleTextView, ContentTextView;
public HolderQna(#NonNull View itemView) {
super(itemView);
titleTextView = itemView.findViewById(R.id.item_post_title);
ContentTextView = itemView.findViewById(R.id.item_post_content);
}
}
}
Can you please change the code in your HolderQna to:
class HolderQna extends RecyclerView.ViewHolder{
/*holds views of recyclerview*/
private TextView titleTextView, ContentTextView;
public HolderQna(#NonNull View itemView) {
super(itemView);
titleTextView = itemView.findViewById(R.id.item_post_title);
ContentTextView = itemView.findViewById(R.id.item_post_content);
}
public void bind(qna: ModelQna){
titleTextView.setText(qna.qnaTitle);
ContentTextView.setText(qna.qnaContent);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//handle item clicks, show item details
}
});
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//handle item clicks, show item details
}
});
}
}
And your onBindViewHolder override of the AdapterQna to:
#Override
public void onBindViewHolder(#NonNull HolderQna holder, int position) {
ModelQna modelQna = qnaList.get(position);
String id = modelQna.getQnaId();
String uid = modelQna.getUid();
String qnaContent = modelQna.getQnaContent();
String qnaTitle = modelQna.getQnaTitle();
String timestamp = modelQna.getTimestamp();
//set data
holder.bind(modelQna);
}
Finally change your loadQna() function declaration as follows:
private void loadAllQna() {
qnaList = new ArrayList<>();
//get all products
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Employees");
reference.child(firebaseAuth.getUid()).child("Qna").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
//before getting reset List
qnaList.clear();
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
ModelQna modelQna = dataSnapshot.getValue(ModelQna.class);
qnaList.add(modelQna);
}
adapterQna = new AdapterQna(this, qnaList);
qnaRv.setAdapter(adapterQna);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseerror) {
Log.e("QnaActivity", databaseError.toString());
}
});
}
As far as I can see in your screenshot, the Qna node it's not nested under any UID, but directly under the Employees node. So when you attach a listener to the following node:
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Employees");
reference.child(firebaseAuth.getUid()).child("Qna").addValueEventListener(/*...*/);
You will not be able to get any results, because such a reference doesn't exist. To solve this, you either create a reference that points exactly to "Qna":
DatabaseReference db = FirebaseDatabase.getInstance().getReference();
DatabaseReference qnaRef = db.child("Employees").child("Qna");
qnaRef.addValueEventListener(/*...*/);
Or you move the "Qna" node under the UID of the user, and leave the code unchanged.
Besides that, there is also another problem. The name of the fields in your ModelFaq class are different than the name of the properties in your database. You have in your ModelFaq class four fields called faqId, faqTitle, faqContent, faqCategory, all starting with faq while in the database I see that the names are different, qnaId, qnaTitle, qnaContent, qnaCategory, all are starting wiht qna, and this is not correct. So in order to be able to map a node into an object of type ModelFaq, the names must match. The only two fields that match are the timestamp and the uid.
In this case, you have two solutions. The first one would to change the name of your fieds in the ModelFaq class according to what it already exists in the database or you can use the PropertyName annotation in front of the getters like this:
#PropertyName("qnaId")
public String getFaqId() {
return faqId;
}
I'm basically building a chatting app, the home page shows RecyclerView items of users who are friends. My HomeActivity passes users of the User class to the adapter. The adapter takes each user info and current user info to look up the "chats" firebase database for the last message and last message time to show on the homepage items.
Homepage Items
As my User class doesn't have any field "last message time" I cannot compare one user to another for their last message time.
Now how do I compare the recycler view items to bring the latest message to the top?
User.Java
public class User {
private String userId, name, username, email, profileImage, token;
}
Message.Java
public class Message {
private String messageId, message, senderId, imageUrl;
private long timestamp;
private int feeling = -1;
}
Firebase database structure
chats -
CurrentUserID+ReceiverID
- lastMsg
- lastMsgTime
- messages
messageId
- message
- timestamp
HomeActivity.java
ArrayList<User> users; //declared above onCreate method
users = new ArrayList<>(); //onCreate method
homeAdapter = new HomeAdapter(this, users);
binding.homeRecyclerView.setAdapter(homeAdapter);
database.getReference().child("users").addValueEventListener(new ValueEventListener() {
#SuppressLint("NotifyDataSetChanged")
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
users.clear();
for (DataSnapshot snapshot1 : snapshot.getChildren()){
User user = snapshot1.getValue(User.class);
if(!user.getUserId().equals(mAuth.getUid())){
database.getReference().child("users")
.child(mAuth.getUid())
.child("friendList")
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot snapshot2 : snapshot.getChildren()){
String check = String.valueOf(snapshot2.getValue());
if(check.equals(user.getUserId())){
Log.d("YESCheck", user.getUsername());
users.add(user);
}
}
Collections.sort(users, new Comparator<User>() {
#Override
public int compare(User user, User t1) {
return user.getName().compareToIgnoreCase(t1.getName());
}
});
homeAdapter.notifyDataSetChanged();
progressDialog.dismiss();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
HomeAdapter.java
public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.HomeViewHolder> {
FirebaseAuth mAuth;
FirebaseDatabase database;
Context context;
ArrayList<User> users;
String senderName;
public HomeAdapter(Context context, ArrayList<User> users) {
this.context = context;
this.users = users;
}
#NonNull
#Override
public HomeViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.activity_home_item, parent, false);
return new HomeViewHolder(view);
}
public void onBindViewHolder(#NonNull HomeViewHolder holder, int position) {
//HomeViewHolder viewHolder = (HomeViewHolder) holder;
User user = users.get(position);
mAuth = FirebaseAuth.getInstance();
database = FirebaseDatabase.getInstance();
String senderId = mAuth.getUid();
String senderRoom = senderId + user.getUserId();
holder.binding.friendName.setText(user.getName());
Picasso.get().load(user.getProfileImage()).into(holder.binding.friendProfilePic);
holder.binding.friend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, ChattingActivity.class);
intent.putExtra("userName", user.getName());
intent.putExtra("profilePic", user.getProfileImage());
intent.putExtra("userId", user.getUserId());
intent.putExtra("token", user.getToken());
//intent.putExtra("senderName", senderName);
context.startActivity(intent);
}
});
database.getReference().child("chats")
.child(senderRoom).addValueEventListener(new ValueEventListener() {
#SuppressLint("SetTextI18n")
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()){
String lastMsg = snapshot.child("lastMsg").getValue(String.class);
long time = snapshot.child("lastMsgTime").getValue(Long.class);
#SuppressLint("SimpleDateFormat")
SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm a");
holder.binding.friendLastMsg.setText(lastMsg);
holder.binding.friendLastMsgTime.setText(dateFormat.format(new Date(time)));
}
else {
holder.binding.friendLastMsg.setText("Tap to chat");
holder.binding.friendLastMsgTime.setText("");
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
#Override
public int getItemCount() {
return users.size();
}
#SuppressWarnings("InnerClassMayBeStatic")
protected class HomeViewHolder extends RecyclerView.ViewHolder {
ActivityHomeItemBinding binding;
public HomeViewHolder(#NonNull View view) {
super(view);
binding = ActivityHomeItemBinding.bind(view);
}
}
}
I am doing work on the geofencing app as I have an activity named Location history logs where I want to retrieve each data node of date (20-Mar-2019) from location logs in a separate card view and (21-Mar-2019) from location logs in a separate card view and so on to the current date how can I do it?
here is a link of my firebase database:
Here is my Model class:
public class locationHistoryModel {
private String Address, Key;
private long Entered, Exited;
public locationHistoryModel() {
}
public locationHistoryModel(String address_child, String key, long entered) {
this.Address = address_child;
Key = key;
Entered = entered;
}
public String getAddress() {
return this.Address;
}
public void setAddress(String address) {
this.Address = address;
}
public String getKey() {
return Key;
}
public void setKey(String key) {
Key = key;
}
public long getEntered() {
return Entered;
}
public void setEntered(long entered) {
Entered = entered;
}
public long getExited() {
return Exited;
}
public void setExited(long exited) {
Exited = exited;
}
}
Here is my Adapter class:
public class LocationhistoryAdapter extends RecyclerView.Adapter<LocationhistoryAdapter.MyViewHolder>{
private Context mctx;
private ArrayList<locationHistoryModel> locationHistories;
public LocationhistoryAdapter(Context context, ArrayList<locationHistoryModel> locationHistoryArrayList )
{
mctx = context;
locationHistories = locationHistoryArrayList;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
return new LocationhistoryAdapter.MyViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_location_historyadapter,viewGroup,false));
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.Addresstxt.setText(locationHistories.get(i).getAddress());
myViewHolder.EnterTimeTxt.setText(String.valueOf(locationHistories.get(i).getEntered()));
myViewHolder.location.setText(locationHistories.get(i).getKey());
}
#Override
public int getItemCount() {
return locationHistories.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder
{
TextView Addresstxt,EnterTimeTxt,location;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
Addresstxt = itemView.findViewById(R.id.Address_child);
EnterTimeTxt = itemView.findViewById(R.id.Entered_timestamp);
location = itemView.findViewById(R.id.Location_child);
}
}
}
Here is my MainActivity class:
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
ArrayList<locationHistoryModel> locationHistoryList;
DatabaseReference databaseReference;
DatabaseReference databaseReference1;
DatabaseReference databaseReference2;
DatabaseReference databaseReference3;
String date;
String location;
locationHistoryModel historyModel;
LocationhistoryAdapter locationAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.childsRecycler);
locationHistoryList = new ArrayList<>();
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.scrollToPosition(0);
databaseReference = FirebaseDatabase.getInstance().getReference("Child");
databaseReference1 = databaseReference.child("+923452267601")
.child("03326325635")
.child("LocationLogs");
databaseReference1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
date = dataSnapshot1.getKey();
System.out.println(date + "dateee keeeeeyyyyy");
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
databaseReference2 = databaseReference.child("+923452267601")
.child("03326325635")
.child("Locations");
databaseReference2.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
location = dataSnapshot1.getKey();
System.out.println(location + "Location Key");
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
System.out.println("03326325635");
databaseReference3 = databaseReference.child("+923452267601")
.child("03326325635")
.child("LocationLogs");
databaseReference3.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
historyModel = dataSnapshot.child(date).child(location).getValue(locationHistoryModel.class);
historyModel.setKey(location);
locationHistoryList.add(historyModel);
System.out.println(historyModel.getAddress() + "haha" + historyModel.getKey() + "" + historyModel.getEntered());
locationAdapter = new LocationhistoryAdapter(MainActivity.this, locationHistoryList);
recyclerView.setAdapter(locationAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
This is my first Firebase app and I am trying to retrieve a list of chat messages. The loop stops and I don't know why and how to fix it
The Error:
com.google.firebase.database.DatabaseException: Can't convert object
of type java.lang.String to type com.venomapps.amchat.Model.Chat
The Error is here
Chat chat = snapshot.getValue(Chat.class);
Error Function
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mchat.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Chat chat = snapshot.getValue(Chat.class);
if(chat.getReceiver().equals(myid) && chat.getSender().equals(userid) ||
chat.getReceiver().equals(userid) && chat.getSender().equals(myid)){
mchat.add(chat);
}
messageAdapter = new MessageAdapter(MessageActivity.this, mchat, imageurl);
recyclerView.setAdapter(messageAdapter);
}
}
Chat class
public class Chat {
private String sender;
private String receiver;
private String message;
public Chat(String sender, String receiver, String message) {
this.sender = sender;
this.receiver = receiver;
this.message = message;
}
public Chat() {
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
Adapter
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.ViewHolder> {
public static final int MSG_TYPE_LEFT = 0;
public static final int MSG_TYPE_RIGHT = 1;
private Context mContext;
private List<Chat> mChat;
private String imageurl;
FirebaseUser fuser;
public MessageAdapter(Context mContext, List<Chat> mChat, String imageurl){
this.mChat = mChat;
this.mContext = mContext;
this.imageurl = imageurl;
}
#NonNull
#Override
public MessageAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if (viewType == MSG_TYPE_RIGHT) {
View view = LayoutInflater.from(mContext).inflate(R.layout.chat_item_right, parent, false);
return new MessageAdapter.ViewHolder(view);
} else {
View view = LayoutInflater.from(mContext).inflate(R.layout.chat_item_left, parent, false);
return new MessageAdapter.ViewHolder(view);
}
}
#Override
public void onBindViewHolder(#NonNull MessageAdapter.ViewHolder holder, int position) {
Chat chat = mChat.get(position);
holder.show_message.setText(chat.getMessage());
if(imageurl.equals("default")){
holder.profile_image.setImageResource(R.mipmap.ic_launcher);
} else {
Glide.with(mContext).load(imageurl).into(holder.profile_image);
}
}
#Override
public int getItemCount() {
return mChat.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView show_message;
public ImageView profile_image;
public ViewHolder(View itemView){
super(itemView);
show_message = itemView.findViewById(R.id.show_message);
profile_image = itemView.findViewById(R.id.profile_image);
}
}
#Override
public int getItemViewType(int position) {
fuser = FirebaseAuth.getInstance().getCurrentUser();
if(mChat.get(position).getSender().equals(fuser.getUid())){
return MSG_TYPE_RIGHT;
} else {
return MSG_TYPE_LEFT;
}
}
}
Edit :
because i can't determine where is the problem
Structure Image
The Whole Message Activity
import de.hdodenhof.circleimageview.CircleImageView;
public class MessageActivity extends AppCompatActivity {
CircleImageView profile_image;
TextView username;
FirebaseUser fuser;
DatabaseReference reference;
ImageButton btn_send;
EditText text_send;
MessageAdapter messageAdapter;
List<Chat> mchat;
RecyclerView recyclerView;
Intent intent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message);
// Toolbar
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
// Recycler View
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
profile_image = findViewById(R.id.profile_image);
username = findViewById(R.id.username);
btn_send = findViewById(R.id.btn_send);
text_send = findViewById(R.id.text_send);
intent = getIntent();
final String userid = intent.getStringExtra("userid");
fuser = FirebaseAuth.getInstance().getCurrentUser();
btn_send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String msg = text_send.getText().toString();
if(!msg.equals("")){
sendMessage(fuser.getUid(), userid, msg);
} else {
Toast.makeText(MessageActivity.this, "You can't send empty message", Toast.LENGTH_SHORT).show();
}
text_send.setText("");
}
});
reference = FirebaseDatabase.getInstance().getReference("Users").child(userid);
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
username.setText(user.getUsername());
if(user.getImageURL().equals("default")){
profile_image.setImageResource(R.mipmap.ic_launcher);
} else {
Glide.with(MessageActivity.this).load(user.getImageURL()).into(profile_image);
}
readMessage(fuser.getUid(), userid, user.getImageURL());
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void sendMessage(String sender, String receiver, String message){
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("sender", sender);
hashMap.put("receiver", receiver);
hashMap.put("message", message);
reference.child("Chats").push().setValue(hashMap);
}
private void readMessage(final String myid, final String userid, final String imageurl){
mchat = new ArrayList<>();
reference = FirebaseDatabase.getInstance().getReference("Chats");
reference.addValueEventListener(new ValueEventListener() {
#Override
/*public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mchat.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Chat chat = snapshot.getValue(Chat.class);
if(chat.getReceiver().equals(myid) && chat.getSender().equals(userid) ||
chat.getReceiver().equals(userid) && chat.getSender().equals(myid)){
mchat.add(chat);
}
messageAdapter = new MessageAdapter(MessageActivity.this, mchat, imageurl);
recyclerView.setAdapter(messageAdapter);
}
} */
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mchat.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Chat chat = snapshot.getValue(Chat.class);
if(chat.getReceiver().equals(myid) && chat.getSender().equals(userid) ||
chat.getReceiver().equals(userid) && chat.getSender().equals(myid)){
mchat.add(chat);
}
messageAdapter = new MessageAdapter(MessageActivity.this, mchat, imageurl);
recyclerView.setAdapter(messageAdapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Good news, it's an easy fix.
The issue is that you're not pushing chat data properly in the picture below. Instead of having a path with several chats, you're just having 1 chat message.
The solution
Your database should look like this
The highlighted yellow keys are called push ids or push keys.
You are most likely saving your chat data like this:
FirebaseDatabase.getInstance().getReference().child("Chats").setValue(chatMessage);
You will accomplish what you want by adding in a push() before the setValue call.
FirebaseDatabase.getInstance().getReference().child("Chats").push().setValue(chatMessage);
i want to build a Presense System with firebase but when i click join in toolbar, the app was forced stop.
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.app.PresenseSystem.User
ListUsersActivity
public class ListUsersActivity extends AppCompatActivity {
DatabaseReference onlineRef, currentUserRef, counterRef;
private FirebaseFirestore firebaseFirestore;
FirebaseRecyclerAdapter<User, ListViewHolder> adapter;
RecyclerView ListOnline;
RecyclerView.LayoutManager layoutManager;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_users);
ListOnline = (RecyclerView) findViewById(R.id.online_list);
ListOnline.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
ListOnline.setLayoutManager(layoutManager);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("User lists");
setSupportActionBar(toolbar);
onlineRef = FirebaseDatabase.getInstance().getReference().child(".info/connected");
counterRef = FirebaseDatabase.getInstance().getReference("lastOnline");
currentUserRef = FirebaseDatabase.getInstance().getReference("lastOnline").child(FirebaseAuth.getInstance().getCurrentUser().getUid());
Query QueryRef = counterRef.orderByKey();
setupSystem();
FirebaseRecyclerOptions Options = new FirebaseRecyclerOptions.Builder<User>().setQuery(QueryRef, User.class).build();
adapter = new FirebaseRecyclerAdapter<User, ListViewHolder>(Options) {
#Override
protected void onBindViewHolder(ListViewHolder holder, final int position, final User model) {
holder.setName(model.getEmail());
}
#Override
public ListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.user_lists, parent, false);
return new ListViewHolder(view);
}
};
adapter.notifyDataSetChanged();
ListOnline.setAdapter(adapter);
}
private void setupSystem() {
onlineRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue(Boolean.class)) {
currentUserRef.onDisconnect().removeValue();
counterRef.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.setValue(new User(FirebaseAuth.getInstance().getCurrentUser().getEmail(), "Online"));
adapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
counterRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot postSnapshot:dataSnapshot.getChildren())
{
User user= postSnapshot.getValue(User.class);
Log.d("LOG",""+user.getEmail()+"is"+user.getStatus());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.main_menu,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.action_join:
counterRef.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.setValue(FirebaseAuth.getInstance().getCurrentUser().getEmail(),"Online");
break;
case R.id.action_logout:
currentUserRef.removeValue();
}
return super.onOptionsItemSelected(item);
}
User
public class User {
public String name;
public String image;
public String email;
public String status;
public String userId;
public User(String email, String online) {
}
public User(String name, String image, String status, String email,String userid) {
this.name = name;
this.image = image;
this.status = status;
this.email= email;
this.userId=userid;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getEmail() {
return email;
}
public String getStatus() {
return status;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}}
ListViewHolder
public class ListViewHolder extends RecyclerView.ViewHolder {
private TextView UserName;
View mView;
public ListViewHolder(View itemView){
super(itemView);
mView = itemView;
}
public void setName(String Name){
TextView email = (TextView)mView.findViewById(R.id.text_email);
email.setText(Name);
}}
Please Change this
counterRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Here
for(DataSnapshot postSnapshot:dataSnapshot.getChildren())
{
User user= postSnapshot.getValue(User.class);
Log.d("LOG",""+user.getEmail()+"is"+user.getStatus());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
into
counterRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user= postSnapshot.getValue(User.class);
Log.d("LOG",""+user.getEmail()+"is"+user.getStatus());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
and make sure that your User.class variables names and types matches the one on your firebase database