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;
}
Related
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());
}
});
I want to get the value of cost and product name from the date child for all products. I am getting null value for above code.
How to get the value from different Childs?
My Java Class:
public class CompleteExpenses {
String product;
String date;
Long cost;
Long quantity;
public CompleteExpenses() {
}
public String getProduct() {
return product;
}
public void setProduct(String product) {
this.product = product;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public Long getCost() {
return cost;
}
public void setCost(Long cost) {
this.cost = cost;
}
public Long getQuantity() {
return quantity;
}
public void setQuantity(Long quantity) {
this.quantity = quantity;
}
}
My adapter:
public class Product_Adapter extends RecyclerView.Adapter {
List<CompleteExpenses> completeExpensesList;
public Product_Adapter(List<CompleteExpenses> completeExpensesList) {
this.completeExpensesList = completeExpensesList;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_layout,parent,false);
ViewHolderClass viewHolderClass=new ViewHolderClass(view);
return viewHolderClass;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
ViewHolderClass viewHolderClass = (ViewHolderClass) holder;
CompleteExpenses completeExpenses = completeExpensesList.get(position);
String strName = String.valueOf(completeExpenses.getProduct());
viewHolderClass.pr.setText(strName);
String strCost = String.valueOf(completeExpenses.getCost());
viewHolderClass.cs.setText(strCost);
}
#Override
public int getItemCount() {
return completeExpensesList.size();
}
public class ViewHolderClass extends RecyclerView.ViewHolder{
TextView pr,cs;
public ViewHolderClass(#NonNull View itemView) {
super(itemView);
pr = (TextView) itemView.findViewById(R.id.tv_productname);
cs = (TextView) itemView.findViewById(R.id.tv_costsum);
}
}
}
Java activity:
public class complete_expenses extends AppCompatActivity {
List<CompleteExpenses> completeExpenses;
RecyclerView recyclerView;
Product_Adapter product_adapter;
DatabaseReference databaseReference,databaseReference1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_complete_expenses);
recyclerView=findViewById(R.id.rv_products);
recyclerView.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(llm);
databaseReference= FirebaseDatabase.getInstance().getReference().child("Project 1").child("CompleteExpenses");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
completeExpenses = new ArrayList<CompleteExpenses>();
CompleteExpenses e = snapshot.getValue(CompleteExpenses.class);
completeExpenses.add(e);
product_adapter=new Product_Adapter(completeExpenses);
recyclerView.setAdapter(product_adapter);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
Firebase structure:
You're reading all data from Project 1/CompleteExpenses and are then trying to read a single object with properties cost, date, product and quantity from there.
If we look at your JSON however, the Project 1/CompleteExpenses doesn't have those properties. Instead those properties exist on a child node (and presumably other child nodes) two levels lower in your JSON.
So you'll either need to read data from the lower level in your JSON:
databaseReference= FirebaseDatabase.getInstance().getReference()
.child("Project 1/CompleteExpenses/M-Sand/11-2-2021");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
completeExpenses = new ArrayList<CompleteExpenses>();
CompleteExpenses e = snapshot.getValue(CompleteExpenses.class);
Or you'll need to navigate over the data that you've read in the onDataChange:
databaseReference= FirebaseDatabase.getInstance().getReference().child("Project 1").child("CompleteExpenses");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
completeExpenses = new ArrayList<CompleteExpenses>();
for (DataSnapshot nameSnapshot: snapshot.getChildren()) {
for (DataSnapshot dateSnapshot: nameSnapshot.getChildren()) {
CompleteExpenses e = dateSnapshot.getValue(CompleteExpenses.class);
completeExpenses.add(e);
}
}
product_adapter=new Product_Adapter(completeExpenses);
recyclerView.setAdapter(product_adapter);
}
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 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));
}
I have a database structure like this:
"users": {
"school": {
userId (randomkey) {
"email": "email#emai.email"
"provider": "provider"
}
}
}
I'm using a recycler view where users can add each other to a group. I'm showing the email for the user in the recycler view and that works fine. But the problem is that I need to retrieve the userId key for the email that is clicked on and append that to a List that I then push to firebase. I'm doing all that with this code.
Adapter class
class RecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ItemClickListenerPeopleToAdd itemClickListenerPeopleToAdd;
public TextView emailLbl;
public RecyclerViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
emailLbl = (TextView) itemView.findViewById(R.id.emailLbl);
}
public void setItemClickListenerPeopleToAdd(ItemClickListenerPeopleToAdd itemClickListenerPeopleToAdd) {
this.itemClickListenerPeopleToAdd = itemClickListenerPeopleToAdd;
}
#Override
public void onClick(View v) {
itemClickListenerPeopleToAdd.onClick(v, getAdapterPosition());
}
}
public class PeopleToAddAdapter extends RecyclerView.Adapter<RecyclerViewHolder> {
private static final String TAG = "Working";
public ArrayList<String> peopleList = new ArrayList<String>();
private List<ModelProject> mModelList;
public PeopleToAddAdapter(List<ModelProject> modelList) {
mModelList = modelList;
}
private Context context;
private List<PeopleToAdd> mPeopleToAdd;
public List<PeopleToAdd> mList;
public PeopleToAddAdapter(Context con, List<PeopleToAdd> list) {
this.context = con;
this.mPeopleToAdd = list;
}
#NonNull
#Override
public RecyclerViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.people_to_add_listview, parent, false);
return new RecyclerViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull RecyclerViewHolder holder, int position) {
final PeopleToAdd listItem = mPeopleToAdd.get(position);
holder.emailLbl.setText(listItem.getEmail());
holder.setItemClickListenerPeopleToAdd(new ItemClickListenerPeopleToAdd() {
#Override
public void onClick(View view, int position) {
Toast.makeText(context, "Click" + listItem.getEmail(), Toast.LENGTH_SHORT).show();
peopleList.add(listItem.toString());
Log.d("value", String.valueOf(peopleList));
}
});
}
#Override
public int getItemCount() {
return mPeopleToAdd.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView emailLbl;
public MyViewHolder(View itemView) {
super(itemView);
emailLbl = (TextView) itemView.findViewById(R.id.emailLbl);
}
}
}
PeopleToAdd
public class PeopleToAdd {
private String email;
private String provider;
public PeopleToAdd(String email, String provider) {
this.email = email;
this.provider = provider;
}
public PeopleToAdd() {
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getProvider() {
return provider;
}
public void setProvider(String provider) {
this.provider = provider;
}
}
Activity class
listItems = new ArrayList<>();
schoolList = new ArrayList<>();
adapter = new PeopleToAddAdapter(this, listItems);
recyclerView.setAdapter(adapter);
mGetSchool = mDatabase.getReference().child("users").child(mCurrentUserId).child("schoolName");
protected void onStart() {
super.onStart();
mGetSchool.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
childPath = dataSnapshot.getValue(String.class);
//peopleAddedTxtView.setText(childPath);
mPeopleToAdd = mDatabase.getReference().child("users").child(childPath);
mPeopleToAdd.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
PeopleToAdd peopleToAdd = dataSnapshot.getValue(PeopleToAdd.class);
listItems.add(peopleToAdd);
test = dataSnapshot.getKey();
Log.d(TAG, test);
peopleToAddAdapter = new PeopleToAddAdapter(SetProject.this, listItems);
recyclerView.setAdapter(peopleToAddAdapter);
peopleToAddAdapter.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) {
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
I'm somehow getting a strange path as the userID
example: "com.appName.Services.PeopleToAdd#ca8f01". How can I get the right userId (the random key generated by firebase). I have it in the "test" String in activity but how can I add that to the List when a user clicks on that user in the reyclerView. I hope you understand me. Thank you in advance.
A snapshot contains two main things: the key from where the data was loaded, and the value that was loaded. Right now your onChildAdded only uses the value, and throws the key away:
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
PeopleToAdd peopleToAdd = dataSnapshot.getValue(PeopleToAdd.class);
listItems.add(peopleToAdd);
test = dataSnapshot.getKey();
Log.d(TAG, test);
peopleToAddAdapter = new PeopleToAddAdapter(SetProject.this, listItems);
recyclerView.setAdapter(peopleToAddAdapter);
peopleToAddAdapter.notifyDataSetChanged();
}
And since you need the key later in your code, you can't retrieve it anymore. The value doesn't contain the key.
One solution is to add the key to you PeopleToAdd class. Based on the answer I gave to Is there a way to store Key in class which I cast from Firebase object?, that could look like this for you:
public class PeopleToAdd {
#Exclude
public String key;
private String email;
private String provider;
public PeopleToAdd(String email, String provider) {
this.email = email;
this.provider = provider;
}
public PeopleToAdd() {
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getProvider() {
return provider;
}
public void setProvider(String provider) {
this.provider = provider;
}
}
And then modify your onChildAdded to set the key on the PeopleToAdd it instantiated from the value:
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
PeopleToAdd peopleToAdd = dataSnapshot.getValue(PeopleToAdd.class);
peopleToAdd.key = dataSnapshot.getKey();
listItems.add(peopleToAdd);
peopleToAddAdapter = new PeopleToAddAdapter(SetProject.this, listItems);
recyclerView.setAdapter(peopleToAddAdapter);
peopleToAddAdapter.notifyDataSetChanged();
}
Now you can get the key of the PeopleToAdd from its key field.