I get this error when I run the program:
com.cdirect.agenda2.AllEvents$1.onDataChange(AllEvents.java:47)
-Events events = dataSnapshot.getValue(Events.class);
I want to get all data from my FirebaseDatabase. I created Events.java. It has getter and setters. MyAdapter is adapting for RecyclerView on AllEvents.java. I want to show all data on AllEvents.java.
But I cannot success. Can you help me?
MyAdapter.java:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
Context context;
ArrayList<Events> list;
public MyAdapter(Context context, ArrayList<Events> list) {
this.context = context;
this.list = list;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.evententry,parent,false);
return new MyViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
Events events = list.get(position);
holder.plan.setText(events.getPlan());
holder.note.setText(events.getNote());
holder.date.setText(events.getDate());
holder.time.setText(events.getTime());
holder.remb.setText(events.getRemb());
}
#Override
public int getItemCount() {
return list.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder{
TextView id, plan, note, date, time, remb;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
id = itemView.findViewById(R.id.tvIdCard);
plan = itemView.findViewById(R.id.tvPlanCard);
note = itemView.findViewById(R.id.tvNoteCard);
date = itemView.findViewById(R.id.tvDateCard);
time = itemView.findViewById(R.id.tvTimeCard);
remb = itemView.findViewById(R.id.tvRememberCard);
}
}
MyEvents.java
public class AllEvents extends AppCompatActivity {
RecyclerView recyclerView;
ArrayList<Events> list;
DatabaseReference dbRef;
MyAdapter adapter;
#Override
public void onBackPressed() {
super.onBackPressed();
startActivity(new Intent(AllEvents.this, MainActivity.class));
finish();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_all_events);
recyclerView = findViewById(R.id.recycleView);
dbRef = FirebaseDatabase.getInstance().getReference("Events");
list = new ArrayList<>();
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new MyAdapter(this, list);
recyclerView.setAdapter(adapter);
dbRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot dataSnapshot: snapshot.getChildren()){
Events events = dataSnapshot.getValue(Events.class);
list.add(events);
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
Events.java
public class Events {
String id;
String plan;
String note;
String date;
String time;
String remb;
public Events(String id, String plan, String note, String date, String time, String remb) {
this.id = id;
this.plan = plan;
this.note = note;
this.date = date;
this.time = time;
this.remb = remb;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPlan() {
return plan;
}
public void setPlan(String plan) {
this.plan = plan;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
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 getRemb() {
return remb;
}
public void setRemb(String remb) {
this.remb = remb;
}
}
My Database is:
enter image description here
First try to make them private for the Event class.
private String id;
private String plan;
private String note;
private String date;
private String time;
private String remb;
Second, change adapter = new MyAdapter(this, list); line to here. Additional here, you need handle whenonCancelled also.
dbRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot dataSnapshot: snapshot.getChildren()){
Events events = dataSnapshot.getValue(Events.class);
list.add(events);
}
adapter = new MyAdapter(this, list);
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.i("???", "onCancelled Error: " + error.getMessage());
}
});
Related
I am creating an application and I need to use a nested FirebaseRecyclerAdapter. But I can't find examples on the Internet of how to do it correctly, maybe someone can show with an example how to do it correctly.
Here is my main adapter inside which I need to implement the second adapter:
FirebaseRecyclerOptions options = new FirebaseRecyclerOptions.Builder<DataSnapshot>()
.setLifecycleOwner((LifecycleOwner)mContext)
.setQuery(FirebaseDatabase.getInstance().getReference("Posts").child(postId).child("Comments"), new SnapshotParser<DataSnapshot>() {
#NonNull
#Override
public DataSnapshot parseSnapshot(#NonNull DataSnapshot snapshot) {
return snapshot;
}
}).build();
adapter = new FirebaseRecyclerAdapter<DataSnapshot, CommentAdapter>(options)
{
#NonNull
#Override
public CommentAdapter onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.comments, parent, false);
return new CommentAdapter(view);
}
#Override
protected void onBindViewHolder(#NonNull CommentAdapter holder, int position, #NonNull DataSnapshot model) {
String comment = model.child("comment").getValue(String.class);
Long dateLong = Long.parseLong(model.child("time").getValue(String.class));
commentID = model.child("commentId").getValue(String.class);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyy HH:mm");
Date date = new Date(dateLong);
Query query = postsReference.orderByKey().equalTo(postId);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot dataSnapshot : snapshot.getChildren())
{
String image = dataSnapshot.child("avatarUri").getValue(String.class);
String nickname = dataSnapshot.child("nickname").getValue(String.class);
Picasso.get().load(image).into(holder.avatar);
holder.nick.setText(nickname);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
holder.comment.setText(comment);
holder.date.setText(simpleDateFormat.format(date));
holder.reply.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
writeComment.setText("#" + holder.nick.getText()+" ");
replyLayout.setVisibility(View.VISIBLE);
replyLayout.setBackgroundColor(Color.parseColor("#FF262726"));
replyTo.setText("Replying to " + holder.nick.getText());
}
});
replyLinearLayoutManager = new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false);
holder.mRecyclerView.setLayoutManager(replyLinearLayoutManager);
holder.mRecyclerView.setHasFixedSize(true);
FirebaseRecyclerAdapter replyAdapter = setReplyAdapter();
holder.mRecyclerView.setAdapter(replyAdapter);
replyAdapter.startListening();
}
};
Reply class:
public class Reply {
private String userId;
private String comment;
private String date;
private String commentId;
public Reply()
{
}
public Reply(String userId, String comment, String date, String commentId)
{
this.comment = comment;
this.userId = userId;
this.date = date;
this.commentId = commentId;
}
public String getCommentId() {
return commentId;
}
public void setCommentId(String commentId) {
this.commentId = commentId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
ReplyRecyclerViewAdapter:
public class ReplyRecyclerViewAdapter extends RecyclerView.ViewHolder{
CircleImageView avatar;
TextView nick, comment, date, reply;
public ReplyRecyclerViewAdapter(#NonNull View view) {
super(view);
avatar = view.findViewById(R.id.commentator_avatar_reply);
nick = view.findViewById(R.id.commentator_nick_reply);
comment = view.findViewById(R.id.comment_text_reply);
date = view.findViewById(R.id.reply_date);
reply = view.findViewById(R.id.reply);
}
}
And this is the method in which I call the nested adapter initialization, but I have a problem that when I try to call a variable of this class from holder, the variable does not see them. I marked these fields with comments in the code.
private FirebaseRecyclerAdapter setReplyAdapter()
{
FirebaseRecyclerOptions optionsReply = new FirebaseRecyclerOptions.Builder<DataSnapshot>()
.setLifecycleOwner((LifecycleOwner)mContext)
.setQuery(FirebaseDatabase.getInstance().getReference("Posts").child(postId).child("Comments").child(commentID).child("Reply"), new SnapshotParser<DataSnapshot>() {
#NonNull
#Override
public DataSnapshot parseSnapshot(#NonNull DataSnapshot snapshot) {
return snapshot;
}
}).build();
FirebaseRecyclerAdapter replyAdapter = new FirebaseRecyclerAdapter<DataSnapshot, ReplyRecyclerViewAdapter>(optionsReply)
{
#NonNull
#Override
public ReplyRecyclerViewAdapter onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.comments, parent, false);
return new ReplyRecyclerViewAdapter(view);
}
#Override
protected void onBindViewHolder(#NonNull ReplyRecyclerViewAdapter holder, int position, #NonNull DataSnapshot model) {
String comment = model.child("comment").getValue(String.class);
Long dateLong = Long.parseLong(model.child("time").getValue(String.class));
commentID = model.child("commentId").getValue(String.class);
replyReference = FirebaseDatabase.getInstance().getReference("Posts").child(postId).child("Comments").child(commentID).child("Reply");
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyy HH:mm");
Date date = new Date(dateLong);
Query query = postsReference.orderByKey().equalTo(postId);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot dataSnapshot : snapshot.getChildren())
{
String image = dataSnapshot.child("avatarUri").getValue(String.class);
String nickname = dataSnapshot.child("nickname").getValue(String.class);
Picasso.get().load(image).into(holder.avatar); //holder.avatar it cannot find avatar variable
holder.nick.setText(nickname); //the same is here
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
holder.comment.setText(comment); //here
holder.date.setText(simpleDateFormat.format(date)); //here
}
};
return replyAdapter;
}
I have a app with chatrooms where I want to show the people in that chatroom.When someone joins the chatroom I set the value of their node to be true.Like this
Like you can see I also have the data of users underit.I want to use the list of members/documentid and use that list to get the data of only those people from the profiledata node.
My class
public class chatroommembers extends AppCompatActivity {
String documentid;
RecyclerView recyclerView;
DatabaseReference peopleref;
DatabaseReference membersref;
private List<User> list;
private MembersAdapter membersAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chatroommembers);
Intent data = getIntent();
documentid = data.getStringExtra("documentid");
peopleref = FirebaseDatabase.getInstance().getReference().child("Users").child("profiledata");
membersref = FirebaseDatabase.getInstance().getReference().child("Chatrooms").child("members").child(documentid);
recyclerView = findViewById(R.id.membersRecycler);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
list = new ArrayList<>();
membersref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot snapshot1:snapshot.getChildren()){
String uid = snapshot1.getKey();
DatabaseReference peoplesref = peopleref.child(uid);
}
membersAdapter = new MembersAdapter(list);
recyclerView.setAdapter(membersAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
public static class User{
String fullname,imageUrl,Uid,Email,Buddies;
public String getFullname() {
return fullname;
}
public User(){
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getUid() {
return Uid;
}
public void setUid(String uid) {
Uid = uid;
}
public String getEmail() {
return Email;
}
public void setEmail(String email) {
Email = email;
}
public String getBuddies() {
return Buddies;
}
public void setBuddies(String buddies) {
Buddies = buddies;
}
public User(String fullname, String imageUrl, String uid, String email, String buddies) {
this.fullname = fullname;
this.imageUrl = imageUrl;
Uid = uid;
Email = email;
Buddies = buddies;
}
}
public class MembersAdapter extends RecyclerView.Adapter<MembersAdapter.MembersViewHolder>{
private List<User> list;
public MembersAdapter(List<User> list) {
this.list = list;
}
#NonNull
#Override
public MembersAdapter.MembersViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.users_recycler_layout,parent,false);
return new MembersAdapter.MembersViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MembersAdapter.MembersViewHolder holder, int position) {
User ld = list.get(position);
holder.name.setText(ld.getFullname());
if (ld.getImageUrl().equals("noimage")){
Glide.with(getApplicationContext()).load(R.drawable.profile).into(holder.circleImageView);
}else{
Glide.with(getApplicationContext()).load(ld.getImageUrl()).into(holder.circleImageView);
}
}
#Override
public int getItemCount() {
return list.size();
}
public class MembersViewHolder extends RecyclerView.ViewHolder{
TextView name;
CircleImageView circleImageView;
public MembersViewHolder(#NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.usersname);
circleImageView = itemView.findViewById(R.id.usersimage);
}
}
}
}
What you're describing is a fairly standard operation known as a client-side join. In Android it'd look something like this:
String chatroomId = "-MBISFO12u2tok9CeWwi";
DatabaseReference membersRef = FirebaseDatabase.getInstance().getReference("Chatrooms/members").child(chatroomId);
DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference("Users/profiledata")
membersRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot memberSnapshot: dataSnapshot.getChildren()) {
String uid = memberSnapshot.getKey();
DatabaseReference userRef = usersRef.child(uid);
userRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot userSnapshot) {
Log.i("USER", userSnapshot.child("Full name").getValue(String.class));
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
}
I'm developing a voting app using Android Studio in Java that uses RecyclerView to list all candidates from the Firebase database. I'm able to list all candidates, but can't implement the vote button to only update a specific candidate's total votes.
The data is picked and displayed in a RecyclerView as follows:
Candidates information in RecyclerView:
I need each time a user clicks on the vote button, the database totalVotes field is updated with a +1.
MyAdapter code:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
Context context;
ArrayList <Candidate> candidates;
private DatabaseReference mDatabase;
public MyAdapter (Context c, ArrayList<Candidate> p){
context = c;
candidates =p;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.cardview, parent, false));
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.name.setText(candidates.get(position).getFirstname());
holder.party.setText(candidates.get(position).getParty());
holder.category.setText(candidates.get(position).getCategory());
Picasso.get().load(candidates.get(position).getImageurl()).into(holder.profilepic);
holder.onClick(position);
}
#Override
public int getItemCount() {
return candidates.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView name, party, category;
ImageView profilepic;
Button vote;
public MyViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.name);
party = (TextView) itemView.findViewById(R.id.party);
profilepic = (ImageView) itemView.findViewById(R.id.profilepic);
category = (TextView) itemView.findViewById(R.id.category);
vote = (Button) itemView.findViewById(R.id.vote);
}
public void onClick(int position){
vote.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
}
}
AllCandidates class that handles the adapter:
private DatabaseReference reference;
private RecyclerView recyclerView;
private ArrayList<Candidate> list;
private ArrayList<CandidateIMage> listimage;
private MyAdapter adapter;
private DatabaseReference imagereference;
FirebaseStorage storage;
StorageReference storageReference;
private static final String TAG = "AllCandidates";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.all_candidates);
//reference= FirebaseDatabase.getInstance().getReference().child("candidates");
recyclerView = (RecyclerView) findViewById(R.id.myRecycler);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
list = new ArrayList<Candidate>();
listimage = new ArrayList<CandidateIMage>();
reference = FirebaseDatabase.getInstance().getReference();
Query presidentquery = reference.child("candidates").orderByChild("category").equalTo("President");
presidentquery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
Candidate p = dataSnapshot1.getValue(Candidate.class);
//String userId = dataSnapshot1.getKey();
//System.out.println("User id to be passed is: "+userId);
list.add(p);
}
adapter = new MyAdapter(AllCandidates.this, list);
recyclerView.setAdapter(adapter);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
};
}
I had tried to add this code to the vote.onclicklostener but it is not working:
public void onClick(final int position){
postRef = FirebaseDatabase.getInstance().getReference("candidates");
vote.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
postRef.runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
Candidate p = mutableData.getValue(Candidate.class);
if (p == null) {
return Transaction.success(mutableData);
} else {
int fetched = p.getTotalVotes();
fetched = fetched + 1;
String userId = postRef.push().getKey();
// Set value and report transaction success
postRef.child(userId).child("totalVotes").setValue(fetched);
//mutableData.setValue(p);
return Transaction.success(mutableData);
}
}
#Override
public void onComplete(DatabaseError databaseError, boolean b,
DataSnapshot dataSnapshot) {
// Transaction completed
Log.d(TAG, "postTransaction:onComplete:" + databaseError);
}
});
}
});
}
My Candidate m0del looks like this:
#IgnoreExtraProperties
public class Candidate {
private String firstname;
private String lastname;
private String party;
private String category;
private String candidateemail;
private String imageurl;
public Integer totalVotes;
// Default constructor required for calls to
// DataSnapshot.getValue(Candidate.class)
public Candidate() {
}
public Candidate(String imageurl, String candidateemail, String firstname, String lastname, String party, String category, Integer totalVotes) {
this.candidateemail = candidateemail;
this.imageurl = imageurl;
this.firstname = firstname;
this.lastname = lastname;
this.party = party;
this.category = category;
this.totalVotes = totalVotes;
}
public String getCandidateemail() {
return candidateemail;
}
public void setCandidateemail(String candidateemail) {
this.candidateemail = candidateemail;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getParty() {
return party;
}
public void setParty(String party) {
this.party = party;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public Integer getTotalVotes() {
return totalVotes;
}
public void setTotalVotes(Integer totalVotes) {
this.totalVotes = totalVotes;
}
public String getImageurl() {
return imageurl;
}
public void setImageurl(String imageurl) {
this.imageurl = imageurl;
}
According to your comment:
When I click on the vote button, it creates a new record in the database, instead of updating the totaLVotes field of the specific voted for a candidate.
This is happening because you are using the transaction in the wrong way. When you are using the following lines of code:
String userId = postRef.push().getKey();
postRef.child(userId).child("totalVotes").setValue(fetched);
You are pushing in the database every time a new total since the call to the .push() generates a new random key each time is called. To update only the totalVotes property, please use the following method:
public static void updateTotalVotes(String operation) {
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference totalVotesRef = rootRef.child("candidates").child("-M35sglMi8onCgvEDzbm").child("totalVotes");
totalVotesRef.runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
Integer votes = mutableData.getValue(Integer.class);
if (votes == null) {
return Transaction.success(mutableData);
}
if (operation.equals("increaseTotalVotes")) {
mutableData.setValue(votes + 1);
} else if (operation.equals("decreaseTotalVotes")){
mutableData.setValue(votes - 1);
}
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
});
}
See, you have to set use a reference that points to the totalVotes property. Now kick it off with:
updateTotalVotes("increaseTotalVotes");
For more information please check the official documentation regarding saving data as transactions.
I am working on an app that you can record your daily tasks and save to database with the day, date and time. You select the day, date and time and also record the startTime and endTime including the tasks then save to database(FireBase). When am trying to retrieve it I get this error
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
If I comment
holder.startTime.setText(data.getTasks().get(0).getStartTime());
holder.endTime.setText( data.getTasks().get(1).getEndTime());
holder.taskTitle.setText(data.getTasks().get(2).getTask());
and leave only
holder.date.setText(data.getDate());
the date will be retrieved else I get the error:
public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.MainViewHolder> {
private List<TimeTableData> tableDataList= new ArrayList<>();
//private List<TimeTableData.Task> taskList = new ArrayList<>();
public void setTaskData(List<TimeTableData> tableDataList) {
this.tableDataList.addAll(tableDataList);
notifyDataSetChanged();
}
#NonNull
#Override
public MainViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.task_item_layout, parent, false);
return new MainViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MainViewHolder holder, int position) {
TimeTableData data = tableDataList.get(position);
holder.date.setText(data.getDate());
holder.startTime.setText(data.getTasks().get(0).getStartTime());
holder.endTime.setText( data.getTasks().get(1).getEndTime());
holder.taskTitle.setText(data.getTasks().get(2).getTask());
}
#Override
public int getItemCount() {
return tableDataList.size();
}
public class MainViewHolder extends RecyclerView.ViewHolder {
public TextView startTime, endTime, taskTitle,date;
public MainViewHolder(#NonNull View itemView) {
super(itemView);
startTime = itemView.findViewById(R.id.start_time);
endTime = itemView.findViewById(R.id.end_time);
taskTitle = itemView.findViewById(R.id.task_title);
date = itemView.findViewById(R.id.date);
}
}
}
recyclerView = findViewById(R.id.rv_task);
recyclerView.setLayoutManager(new LinearLayoutManager(this, RecyclerView.VERTICAL, false));
mainAdapter = new TaskAdapter();
mFirebaseDatabase=FirebaseDatabase.getInstance();
mDataBaseReference =mFirebaseDatabase.getReference().child("timeTable");
mChildEventListener = new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
List<TimeTableData> taskLis = new ArrayList<>();
TimeTableData subTask = dataSnapshot.getValue(TimeTableData.class);
taskLis.add(subTask);
mainAdapter.setTaskData(taskLis);
recyclerView.setAdapter(mainAdapter);
}
#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) {
}
};
mDataBaseReference.addChildEventListener(mChildEventListener);`
public class TimeTableData implements Serializable {
private String id;
private String date;
private List<Task> tasks;
public TimeTableData(){}
public TimeTableData( String date,List<Task> taskList) {
//this.setId(id);
this.setDate(date);
this.setTasks(taskList);
}
// public TimeTableData(long date){
// this.setDate(date);
// }
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public List<Task> getTasks() {
return tasks;
}
public void setTasks(List<Task> tasks) {
this.tasks = tasks;
}
public static class Task {
private String task;
private String startTime;
private String endTime;
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
public String getTask() {
return task;
}
public void setTask(String task) {
this.task = task;
}
public String getStartTime() {
return startTime;
}
public void setStartTime(String startTime) {
this.startTime = startTime;
}
}
}`
I want to be able to retrieve each date with the expected tasks under it.
This is my database structure
I set it up normally in the onBindViewholder
holder.startTime.setText(data.getStartTime());
holder.endTime.setText(data.getEndTime());
holder.taskTitle.setText(data.getTask());
Using viewPager and fragment I set it up to get tasks by index and set to equivalent position
public static Fragment newInstance(TimeTableData timeTableData) {
AllTasksFragment fragment = new AllTasksFragment();
Bundle bundle = new Bundle();
bundle.putParcelable(TABLE_DATA, timeTableData);
fragment.setArguments(bundle);
return fragment;
}
#NonNull
#Override
public Fragment getItem(int position) {
return AllTasksFragment.newInstance(tableDataList.get(position));
}
My RecyclerView not show any data from Firebase. I don't see any errors at logcat so I don't know why. I followed guide from youtube video. But still nothing. I'm using android 8.0 and API 27. Hope Somebody can help.
My Main Activity Code:
public class ViewProduct extends AppCompatActivity {
DatabaseReference ref;
ArrayList<Model> list;
private RecyclerView recyclerView;
private RecyclerView.Adapter viewHolder;
private RecyclerView.LayoutManager layoutManager;
SearchView searchView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_product) ;
ref = FirebaseDatabase.getInstance().getReference().child("buddymealplanneruser").
child("Products");
recyclerView = findViewById(R.id.stallproductRecyclerView);
//recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//SEARCH VIEW
searchView = findViewById(R.id.searchProductStall);
//ADAPTER
list = new ArrayList<>();
viewHolder = new ViewHolder(list);
recyclerView.setAdapter(viewHolder);
}
#Override
protected void onRestart() {
super.onRestart();
if (ref!=null)
{
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists())
{
//list = new ArrayList<>();
list.clear();
for(DataSnapshot ds : dataSnapshot.getChildren())
{
list.add(ds.getValue(Model.class));
}
//ViewHolder viewHolder = new ViewHolder(list);
//recyclerView.setAdapter(viewHolder);
viewHolder.notifyDataSetChanged();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(ViewProduct.this, databaseError.getMessage(),
Toast.LENGTH_SHORT).show();
}
});
}
if (searchView !=null)
{
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s)
{
return false;
}
#Override
public boolean onQueryTextChange(String s) {
search(s);
return true;
}
});
}
}
private void search(String str) {
ArrayList<Model> myList = new ArrayList<>();
for(Model object : list)
{
if(object.getProductName().toLowerCase().contains(str.toLowerCase()))
{
myList.add(object);
}
}
ViewHolder viewHolder = new ViewHolder(myList);
recyclerView.setAdapter(viewHolder);
}
}
My Adapter:
public class ViewHolder extends RecyclerView.Adapter<ViewHolder.MyViewHolder> {
ArrayList<Model> list;
public ViewHolder (ArrayList<Model> list)
{
this.list=list;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_product, viewGroup,false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.productName.setText(list.get(i).getProductName());
myViewHolder.productCalorie.setText(list.get(i).getProductCalorie());
myViewHolder.StallId.setText(list.get(i).getStallId());
myViewHolder.productType.setText(list.get(i).getProductType());
myViewHolder.productServing.setText(list.get(i).getProductServing());
myViewHolder.statusProduct.setText(list.get(i).getStatusProduct());
}
#Override
public int getItemCount()
{
return list.size();
}
class MyViewHolder extends RecyclerView.ViewHolder
{
TextView productName, productCalorie, StallId;
TextView productType, productServing, statusProduct;
ImageView productImageView;
public MyViewHolder (#NonNull View itemView){
super((itemView));
productName = itemView.findViewById(R.id.productTitle);
productCalorie = itemView.findViewById(R.id.productDescriptionCalorie);
StallId = itemView.findViewById(R.id.productDescriptionStallId);
productType = itemView.findViewById(R.id.productDescriptionType);
productServing=itemView.findViewById(R.id.productDescriptionServing);
statusProduct=itemView.findViewById(R.id.productDescriptionAvailibility);
//productImageView = itemView.findViewById(R.id.productImageView);
}
}
}
My Model :
package com.example.buddymealplannerstall.Child;
import android.view.Display;
public class Model {
//String productName, productImage, productCalorie, StallId, productType, productServing, statusProduct;
private String StallId;
private String productCalorie;
private String productImage;
private String productName;
private String productServing;
private String productType;
private String statusProduct;
public Model (String StallId,
String productCalorie,
String productImage,
String productName,
String productServing,
String productType,
String statusProduct){
this.StallId = StallId;
this.productCalorie = productCalorie;
this.productImage = productImage;
this.productName = productName;
this.productServing = productServing;
this.productType = productType;
this.statusProduct = statusProduct;
}
public Model(){
}
public String getStallId() {
return StallId;
}
public void setStallId(String stallId) {
StallId = stallId;
}
public String getProductCalorie() {
return productCalorie;
}
public void setProductCalorie(String productCalorie) {
this.productCalorie = productCalorie;
}
public String getProductImage() {
return productImage;
}
public void setProductImage(String productImage) {
this.productImage = productImage;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getProductServing() {
return productServing;
}
public void setProductServing(String productServing) {
this.productServing = productServing;
}
public String getProductType() {
return productType;
}
public void setProductType(String productType) {
this.productType = productType;
}
public String getStatusProduct() {
return statusProduct;
}
public void setStatusProduct(String statusProduct) {
this.statusProduct = statusProduct;
}
}
Screen Shot of my firebase and my apps.
firebase
my app
According to your comment:
yes, buddymealplanner is my project's name
Please note that there is no need to add the name of your project as a child in the reference. So please change the following line of code:
ref = FirebaseDatabase.getInstance().getReference().child("buddymealplanneruser").
child("Products");
Simply to:
ref = FirebaseDatabase.getInstance().getReference().child("Products");
I dont think you are populating your list, you are sending it empty. From what I can see, you only add items to the list when you are restarting the activity. Try either populating it before sendinig the list, or changing the onRestart() for an onStart() or an onResume().