I'm retrieving list of few users which being added and but are not visible. When I added Toast on item click it shows data null and android studio give warning also in model class the constructor is never used .I'm using ChildEventListener and a custom adapter
Custom adapter code
class CustomMemberAdapter extends RecyclerView.Adapter<SetMeeting_2.User_MemberHolder>{
List<UserModel_member_DP_NAME> mList;
CustomMemberAdapter(List<UserModel_member_DP_NAME> mList) {
this.mList = mList;
}
#Override
public User_MemberHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.set_meeting_userlist_item,parent,false);
return new User_MemberHolder(v);
}
#Override
public void onBindViewHolder(User_MemberHolder holder, int position) {
final UserModel_member_DP_NAME model = mList.get(position);
holder.txt.setText(model.getName());
Picasso.with(holder.itemView.getContext()).load(model.getDp()).into(holder.img);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(view.getContext(), String.valueOf(model.getName()), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return mList.size();
}
}
Model Class code
private static class UserModel_member_DP_NAME {
String dp,name;
UserModel_member_DP_NAME(){}
UserModel_member_DP_NAME(String dp, String name) { //never used warning
this.dp = dp;
this.name = name;
}
public String getDp() {
return dp;
}
public void setDp(String dp) {
this.dp = dp;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
ChildEventListener code
mDatabase = FirebaseDatabase.getInstance().getReference();
defaultQuery = mDatabase.child("users").child(current_user).child("directorylist");
defaultQuery.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
UserModel_member_DP_NAME model = dataSnapshot.getValue(UserModel_member_DP_NAME.class);
memberList.add(model);
adapter.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) {
}
});
recyclerView.setAdapter(adapter);
here is my database structure
Related
I am currently using Value Event Listener in my Code to show messages and it does not shows any error but my only problem is when whenever i add a new send or receive a new message my whole list gets updated all the previous messages are called and it uses a lot of memory currently i am taking care of it my clearing recyclerview every time the value event listener is called but now i want to add Child Event Listener in place of value event listener to save memory but whenever i add child event listener my messages are shown multiple times in recyclerview but after i restart the activity there is only one message in recyclerview.
MyCode
MessageActivity.java
public class MessageActivity extends AppCompatActivity {
CircleImageView profile_image;
TextView user_name;
FirebaseFirestore fstore;
FirebaseAuth fAuth;
FirebaseUser fuser;
DatabaseReference reference;
Toolbar toolbar;
ImageButton imageButton;
EditText textsend;
String userID;
MessageAdapter messageAdapter;
List<Chat> mChat;
RecyclerView recyclerView;
String TAG = "MyTag";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message);
fAuth=FirebaseAuth.getInstance();
fstore=FirebaseFirestore.getInstance();
userID = fAuth.getCurrentUser().getUid();
profile_image=findViewById(R.id.profile_image);
user_name=findViewById(R.id.username);
imageButton=findViewById(R.id.btn_send);
textsend=findViewById(R.id.text_send);
recyclerView=findViewById(R.id.recycler_view2);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager= new LinearLayoutManager(getApplicationContext());
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
toolbar=findViewById(R.id.myToolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
Intent intent=getIntent();
fuser=FirebaseAuth.getInstance().getCurrentUser();
String userid=intent.getStringExtra("userid");
String username= intent.getStringExtra("UserName");
reference = FirebaseDatabase.getInstance().getReference("Users").child(userid);
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
user_name.setText(user.getFirst());
if (user.getImageURL().equals("default")){
profile_image.setImageResource(R.mipmap.ic_launcher);
} else {
//and this
Glide.with(getApplicationContext()).load(user.getImageURL()).into(profile_image);
}
readMessages(fuser.getUid(), userid, user.getImageURL());
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String msg=textsend.getText().toString();
textsend.setText("");
if (!msg.equals("")){
sendMessage(fuser.getUid(),userid,msg);
}
else {
Toast.makeText(MessageActivity.this,"Empty messages cant be send",Toast.LENGTH_SHORT).show();
}
}
});
}
private void sendMessage(String sender, final String receiver, String message) {
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("sender", sender);
hashMap.put("receiver", receiver);
hashMap.put("message", message);
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Chats");
String key = reference.push().getKey();
reference.child(key).setValue(hashMap);
}
private void readMessages(String myid,String userid,String imageurl){
mChat=new ArrayList<>();
reference=FirebaseDatabase.getInstance().getReference("Chats");
reference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Chat chat= dataSnapshot.getValue(Chat.class);
assert chat!=null;
if (chat.getReceiver().equals(myid) && chat.getSender().equals(userid)||
chat.getReceiver().equals(userid)&&chat.getSender().equals(myid)){
chat.setMessageId(dataSnapshot.getKey());
mChat.add(chat);
Log.d(TAG,"msg "+chat.getMessage());
}
messageAdapter=new MessageAdapter(MessageActivity.this,mChat, imageurl);
recyclerView.setAdapter(messageAdapter);
messageAdapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
Chat chat=dataSnapshot.getValue(Chat.class);
chat.setMessageId(dataSnapshot.getKey());
mChat.remove(chat);
messageAdapter.notifyDataSetChanged();
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
/*
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mChat.clear();
for (DataSnapshot snapshot:dataSnapshot.getChildren()) {
Chat chat=snapshot.getValue(Chat.class);
assert chat != null;
if (chat.getReceiver().equals(myid) && chat.getSender().equals(userid)||
chat.getReceiver().equals(userid)&&chat.getSender().equals(myid)){
mChat.add(chat);
Log.d(TAG,"msg "+chat.getMessage());
}
messageAdapter=new MessageAdapter(MessageActivity.this,mChat, imageurl);
recyclerView.setAdapter(messageAdapter);
messageAdapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
*/
}
}
MessageAdapter.java
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;
String imageurl;
FirebaseUser fuser;
public MessageAdapter(Context mContext, List<Chat> mChat,String imageurl) {
this.mContext = mContext;
this.mChat = mChat;
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);
}
holder.show_message.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
String message_id=chat.getMessageId();
Task<Void> task = Utils.removeUser(message_id);
task.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(mContext,"Message Deleted",Toast.LENGTH_SHORT).show();
}
});
return true;
}
});
}
#Override
public int getItemCount() {
return mChat.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView show_message;
public ImageView profile_image;
public ViewHolder(#NonNull 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;
}
}
}
Use below code. Remove ValueEventListener calls. You should add your logic inside onChildAdded
reference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Chat chat= dataSnapshot.getValue(Chat.class);
assert chat!=null;
if (chat.getReceiver().equals(myid) && chat.getSender().equals(userid)||
chat.getReceiver().equals(userid)&&chat.getSender().equals(myid)){
mChat.add(chat);
Log.d(TAG,"msg "+chat.getMessage());
}
messageAdapter=new MessageAdapter(MessageActivity.this,mChat, imageurl);
recyclerView.setAdapter(messageAdapter);
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) {
}
});
I tried so many solutions about this, but none of this resolve my problem. I can not reach the database using recyclerview. I have firebase realtime database data like this;
Tag
--- Main Category
----- keyID
------ main-Category, sub-category
Tags class
public class Tags {
private String id;
private String mainTags;
private String subTags;
public Tags() {}
public Tags(String id, String mainTags, String subTags) {
this.id = id;
this.mainTags = mainTags;
this.subTags = subTags;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getMainTags() {
return mainTags;
}
public void setMainTags(String mainTags) {
this.mainTags = mainTags;
}
public String getSubTags() {
return subTags;
}
public void setSubTags(String subTags) {
this.subTags = subTags;
}
}
and this is TagAdapter
public class TagAdapter extends RecyclerView.Adapter<TagAdapter.ItemViewHolder> {
private List<Tags> mTagList;
private Context mContext;
public TagAdapter(List<Tags> mTagList, Context mContext) {
this.mTagList = mTagList;
this.mContext = mContext;
}
#NonNull
#Override
public ItemViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.each_item_tags, parent,false);
return new ItemViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ItemViewHolder holder, int position) {
Tags tags = mTagList.get(position);
holder.tvTags.setText(tags.getSubTags());
holder.tvMainTags.setText(tags.getMainTags());
}
#Override
public int getItemCount() {
return mTagList.size();
}
public class ItemViewHolder extends RecyclerView.ViewHolder{
private TextView tvMainTags, tvTags;
public ItemViewHolder(#NonNull View itemView) {
super(itemView);
tvMainTags = itemView.findViewById(R.id.tvMainTag);
tvTags = itemView.findViewById(R.id.tvTags);
}
}
}
TagsFragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_tags, container, false);
rvTags = view.findViewById(R.id.rvTags);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
rvTags.setLayoutManager(linearLayoutManager);
rvTags.hasFixedSize();
tagAdapter = new TagAdapter(tagsList, getContext());
rvTags.setAdapter(tagAdapter);
return view;
}
private void getTagView(){
FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference dbRefTags = firebaseDatabase.getReference().child("Tag");
dbRefTags.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
for (DataSnapshot ds : dataSnapshot.getChildren()){
if (ds.exists()) {
try {
Tags tags = ds.getValue(Tags.class);
tagsList.add(tags);
}catch (Exception e){
Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
}else {
Toast.makeText(getContext(), "Bir hata oluştu", Toast.LENGTH_SHORT).show();
}
}
tagAdapter.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) {
}
});
}
There is no error show up when running but i couldn't be able to retrieve data. And i tried firebaseRecyclerView.Adapter also and in the last dependency, i couldn't make it work. I don't know what is wrong in here. how can i solve this?
Get The data with child name ds.child("SubTag").getValue()
dbRefTags.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot parentDS : dataSnapshot.getChildren()) {
Log.d("Tag:", String.valueOf(parentDS.getKey()));
for (DataSnapshot ds : parentDS.getChildren()) {
Tags tags = new Tags();
tags.setMainTag(parentDS.getKey());
tags.setSubTag(ds.child("SubTag").getValue().toString());
Log.d("Tag: -> SubTag)", tags.getSubTag());
tagsList.add(tags);
}
}
tagAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getContext(), databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
I'm making a chat application with RecyclerView and List class to store messages from Firebase Database and want to scroll at the bottom of the recylcerView when Chat Activity is opened but error is.....Adapter always returns zero while calling adapter.getItemcount() method . All messages are being displayed with no problem.
Custom Adapter java file
public class ChatCustomAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private FirebaseUser mUser;
private String currentUser;
private List<ChatModel> msgList;
//Constructor
public ChatCustomAdapter(List<ChatModel> msgList) {
this.msgList = msgList;
FirebaseAuth mAuth = FirebaseAuth.getInstance();
mUser = mAuth.getCurrentUser();
currentUser = mUser.getUid();
}
#Override
public int getItemCount() {
return msgList.size();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
if(viewType==0){
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_single__user_item_layout,parent,false);
return new SelfViewHolder(v);
}else if(viewType==1){
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_single_other_user_item_layout,parent,false);
return new OtherViewHolder(v);
}else{
return null;
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
int layout = holder.getItemViewType();
ChatModel model = msgList.get(position);
String msg = model.getMsg();
if(layout==0){
SelfViewHolder sHolder = (SelfViewHolder)holder;
sHolder.setSelfMsgItems(msg);
}else if(layout==1){
OtherViewHolder oHolder = (OtherViewHolder)holder;
oHolder.setOtherMsgItems(msg);
}
}
#Override
public int getItemViewType(int position) {
super.getItemViewType(position);
int layout;
ChatModel model = msgList.get(position);
String from = model.getFrom();
if(from.equals(currentUser)){
layout=0;
}else{
layout=1;
}
return layout;
}
class SelfViewHolder extends RecyclerView.ViewHolder{
TextView msgtxt,timetxt;
SelfViewHolder(View itemView) {
super(itemView);
msgtxt = itemView.findViewById(R.id.chat_sinhle_user_item_textview);
timetxt = itemView.findViewById(R.id.chat_sinhle_user_item_timeview);
}
void setSelfMsgItems(String data){
msgtxt.setText(data);
}
}
class OtherViewHolder extends RecyclerView.ViewHolder{
TextView msgtxt,timetxt;
public OtherViewHolder(View itemView) {
super(itemView);
msgtxt = itemView.findViewById(R.id.chat_other_user_item_textview);
timetxt = itemView.findViewById(R.id.chat_other_user_item_timeview);
}
public void setOtherMsgItems(String data){
msgtxt.setText(data);
}
}
}
Chat Activity java file
protected void onStart() {
super.onStart();
//region RETREIVING MESSAGES FROM SERVER
msgQ = mDatabase.child("messages").child(current_user).child(otherusername).orderByChild("time");
msgQ.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
ChatModel model = dataSnapshot.getValue(ChatModel.class);
mLsit.add(msgposition++, model);
mAdapter.notifyDataSetChanged();
}
#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) {
}
});
//endregion
recyclerView.scrollToPosition(mAdapter.getItemCount()-1);
}
I think getItemCount() returns zero because you call this method outside of ChildEventListener. So you retrieve itemcount when there are no elements in mLsit yet.
The fastest and a little bit dirty solution here is to put scrollToPosition in onChildAdded method. Also, I would modify code this way
protected void onStart() {
super.onStart();
//region RETREIVING MESSAGES FROM SERVER
msgQ = mDatabase.child("messages").child(current_user).child(otherusername).orderByChild("time");
msgQ.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
ChatModel model = dataSnapshot.getValue(ChatModel.class);
mLsit.add(msgposition, model);
mAdapter.notifyItemInserted(msgposition)
recyclerView.scrollToPosition(msgposition);
msgposition++;
}
#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) {
}
});
//endregion
}
Tried answers found on the internet, actually there is no change to the code as it seem correct but can't find where is the error.
My Input Parameters:
JSON RETURNED:
(I expected a "clocation" child and value but it won't even write that to the tree. Plus, the value of clocation is written to cbudget)
Project Class:
public class Project {
String ctitle, cdetail, clocation, cbudget;
public Project() {
}
public String getCtitle() {
return ctitle;
}
public void setCtitle(String ctitle) {
this.ctitle = ctitle;
}
public String getCdetail() {
return cdetail;
}
public void setCdetail(String cdetail) {
this.cdetail = cdetail;
}
public String getClocation() {
return clocation;
}
public void setClocation(String clocation) {
this.clocation = clocation;
}
public String getCbudget() {
return cbudget;
}
public void setCbudget(String cbudget) {
this.cbudget = cbudget;
}
MyViewHolder
public MyViewHolder(View itemView) {
super(itemView);
titleTxt = (TextView) itemView.findViewById(R.id.titleTxt);
detailTxt = (TextView) itemView.findViewById(R.id.detailTxt);
locationTxt = (TextView) itemView.findViewById(R.id.locationTxt);
budgetTxt = (TextView) itemView.findViewById(R.id.budgetTxt);
itemView.setOnClickListener(this);
}
MyAdapter
public MyAdapter(Context c, ArrayList<Project> projects) {
this.c = c;
this.projects = projects;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(c).inflate(R.layout.model,parent,false);
return new MyViewHolder(v);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
final Project s = projects.get(position);
holder.titleTxt.setText(s.getCtitle());
holder.detailTxt.setText(s.getCdetail());
holder.locationTxt.setText(s.getClocation());
holder.budgetTxt.setText(s.getCbudget());
holder.setItemClickListener(new ItemClickListener() {
#Override
public void onItemClick(int pos) {
//OPEN DETAIL ACTIVITY
openDetailActivity(s.getCtitle(),s.getCdetail(),s.getClocation(),s.getCbudget());
}
});
}
#Override
public int getItemCount() {
return projects.size();
}
//OPEN DETAIL ACTIVITY
private void openDetailActivity(String...details)
{
Intent i=new Intent(c,DetailActivity.class);
i.putExtra("TITLE_KEY",details[0]);
i.putExtra("DETAIL_KEY",details[1]);
i.putExtra("LOCATION_KEY",details[2]);
i.putExtra("BUDGET_KEY",details[3]);
c.startActivity(i);
}
FirebaseHelper
public class FirebaseHelper {
DatabaseReference db;
Boolean saved = null;
ArrayList<Project> projects=new ArrayList<>();
public FirebaseHelper(DatabaseReference db) {
this.db = db;
}
//WRITE IF NOT NULL
public Boolean save(Project project)
{
if(project==null)
{
saved=false;
}
else
{
try
{
db.child("Project").push().setValue(project);
saved=true;
}catch (DatabaseException e)
{
e.printStackTrace();
saved=false;
}
}
return saved;
}
//IMPLEMENT FETCH DATA AND FILL ARRAYLIST
private void fetchData(DataSnapshot dataSnapshot)
{
projects.clear();
for (DataSnapshot ds : dataSnapshot.getChildren())
{
Project project = ds.getValue(Project.class);
projects.add(project);
}
}
//READ THEN RETURN ARRAYLIST
public ArrayList<Project> retrieve() {
db.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return projects;
}
}
Receive and Bind Data:
//RECEIVE DATA
String title = i.getExtras().getString("TITLE_KEY");
String detail = i.getExtras().getString("DETAIL_KEY");
String location = i.getExtras().getString("LOCATION_KEY");
String budget = i.getExtras().getString("BUDGET_KEY");
//BIND DATA
titleTxt.setText(title);
detailTxt.setText(detail);
locationTxt.setText(location);
budgetTxt.setText(budget);
The problem in your code is that you are declaring the ArrayList<Project> projects=new ArrayList<>(); outside onChildAdded() and onChildChanged() methods. This means that your projects ArrayList is null, due the asyncronious behaviour of those methods, which are called before even you add those objects to the list.
To solve this, you need to declare that ArrayList inside fetchData() method right before that for loop.
This change will solve your problem.
I have an activity for searching in firebase, it contains edit text for typing the text and button when I press the button The results supposed to appear in the recyclerview but when I press the button the first time nothing appears unless I hide the keyboard and when I press the second time nothing appears unless the keyboard shows. Is there a solution for this problem?
Code of activity
public class FindDataActivity extends AppCompatActivity {
DatabaseReference db;
FirebaseHelper helper;
MyAdapter adapter;
RecyclerView rv;
EditText findETxt;
Button findBtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_find_data);
//SETUP RECYCLER
rv = (RecyclerView) findViewById(R.id.rvsearch);
rv.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
//INITIALIZE FIREBASE DB
db = FirebaseDatabase.getInstance().getReference("Database");
findETxt = (EditText) findViewById(R.id.findETxt);
findBtn = (Button) findViewById(R.id.find_btn);
}
public void search(View view) {
helper = new FirebaseHelper(db);
final String s = findETxt.getText().toString();
//ADAPTER
adapter = new MyAdapter(FindDataActivity.this, helper.retrieveSearch(s));
db.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
rv.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
This is code of firebase
public class FirebaseHelper {
DatabaseReference db;
Boolean saved=null;
Boolean saved1=null;
ArrayList<Paints> paints=new ArrayList<>();
ArrayList<String> keys=new ArrayList<>();
public FirebaseHelper(DatabaseReference db) {
this.db = db;
}
//WRITE IF NOT NULL
public Boolean save(Paints paint)
{
if(paint==null)
{
saved=false;
}else
{
try
{
db.child("items").push().setValue(paint);
saved=true;
}catch (DatabaseException e)
{
e.printStackTrace();
saved=false;
}
}
return saved;
}
// IN STATE OF UPDATE
public Boolean save1(Paints paint,String k)
{
if(paint==null)
{
saved1=false;
}else
{
try
{
db.child("items").child(k).setValue(paint);
saved1=true;
}catch (DatabaseException e)
{
e.printStackTrace();
saved1=false;
}
}
return saved1;
}
//IMPLEMENT FETCH DATA AND FILL ARRAYLIST
private void fetchData(DataSnapshot dataSnapshot)
{
paints.clear();
for (DataSnapshot ds : dataSnapshot.getChildren())
{
Paints spacecraft=ds.getValue(Paints.class);
paints.add(spacecraft);
}
}
//READ THEN RETURN ARRAYLIST
public ArrayList<Paints> retrieve() {
db.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return paints;
}
//READ THEN RETURN ARRAYLIST OF KEYS IN CASE OF ALL DATA
public ArrayList<String> retrieve1() {
db.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchDataKeys(dataSnapshot);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchDataKeys(dataSnapshot);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return keys;
}
//IMPLEMENT FETCH DATA AND FILL ARRAYLIST WITH ALL KEYS
private void fetchDataKeys(DataSnapshot dataSnapshot)
{
keys.clear();
for (DataSnapshot ds : dataSnapshot.getChildren())
{
keys.add(ds.getKey());
}
}
//READ THEN RETURN ARRAYLIST FOR SEARCH ITEMS IN CASE OF SEARCHING ABOUT ITEM
public ArrayList<Paints> retrieveSearch(final String item) {
db.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchDataSearch(dataSnapshot,item);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchDataSearch(dataSnapshot,item);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return paints;
}
//IMPLEMENT FETCH DATA AND FILL ARRAYLIST WITH ALL PAINTS
private void fetchDataSearch( DataSnapshot dataSnapshot,String item)
{
paints.clear();
//sorting and searching
final DatabaseReference myRef = db.child("items");
Query query = myRef.orderByChild("type").startAt(item)
.endAt(item + "\uf8ff");
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot messageSnapshot : dataSnapshot.getChildren()) {
Paints paint=messageSnapshot.getValue(Paints.class);
paints.add(paint);
//Toast.makeText(FindDataActivity.this, "found " + type + " unit: " + unit + " price " + price, Toast.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
//READ THEN RETURN ARRAYLIST OF KEYS IN CASE OF SEARCH ITEM
public ArrayList<String> retrieve1Search(final String item) {
db.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchDataKeysSearch(dataSnapshot,item);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchDataKeysSearch(dataSnapshot,item);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return keys;
}
//IMPLEMENT FETCH DATA AND FILL ARRAYLIST WITH KEYS IN STATE OF SEARCH
private void fetchDataKeysSearch(DataSnapshot dataSnapshot,String item)
{
keys.clear();
//sorting and searching
final DatabaseReference myRef = db.child("items");
Query query = myRef.orderByChild("type").startAt(item)
.endAt(item + "\uf8ff");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot messageSnapshot : dataSnapshot.getChildren())
{
keys.add(messageSnapshot.getKey());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
code for Adapter
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
Context c;
ArrayList<Paints> paints=new ArrayList<Paints>();
ArrayList<String> keys = new ArrayList<String>();
public MyAdapter(Context c, ArrayList<Paints> paints) {
this.c = c;
this.paints = paints;
//this.keys=keys;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v=LayoutInflater.from(c).inflate(R.layout.model,parent,false);
return new MyViewHolder(v);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
final Paints paint=paints.get(position);
//final String ss=keys.get(position);
holder.typeTxt.setText(paint.getType());
holder.unitTxt.setText(paint.getUnit());
holder.priceTxt.setText(String.valueOf(paint.getPrice()));
holder.setItemClickListener(new ItemClickListener() {
#Override
public void onItemClick(int pos) {
//OPEN DETAI ACTIVITY
openDetailActivity(paint.getType(),paint.getUnit(),paint.getPrice());
}
});
}
#Override
public int getItemCount() {
return paints.size();
}
//OPEN DETAIL ACTIVITY
private void openDetailActivity(String type,String unit, Double price)
{
Intent i=new Intent(c,DetailActivity.class);
i.putExtra("TYPE_KEY",type);
i.putExtra("UNIT_KEY",unit);
i.putExtra("PRICE_KEY", price);
//i.putExtra("K_KEY",s);
c.startActivity(i);
}
}
code for viewholder
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView typeTxt,unitTxt,priceTxt;
ItemClickListener itemClickListener;
public MyViewHolder(View itemView) {
super(itemView);
typeTxt= (TextView) itemView.findViewById(R.id.typeTxt);
unitTxt= (TextView) itemView.findViewById(R.id.unitTxt);
priceTxt= (TextView) itemView.findViewById(R.id.priceTxt);
itemView.setOnClickListener(this);
}
public void setItemClickListener(ItemClickListener itemClickListener)
{
this.itemClickListener=itemClickListener;
}
#Override
public void onClick(View view) {
this.itemClickListener.onItemClick(this.getLayoutPosition());
}
}