Firebase Database getChildrenCount() Android - android

I've tried everything and looked at these questions (one, two, three(vid tut)) for answers and tried them, but still to no avail am I able to set the childrencount that I can clearly see in the logs using an int into a textview.
public class HomeListAdapter extends RecyclerView.Adapter<HomeListAdapter.ViewHolder> {
private static final String TAG = HomeListAdapter.class.getSimpleName();
private DatabaseReference mDatabase;
private Context context;
private List<Recipe> mRecipesList;
private MainActivity mainActivity;
private ProgressBar progressBar;
private int likeCounter = 0;
public HomeListAdapter(Context context, List<Recipe> mRecipesList) {
this.context = context;
this.mRecipesList = mRecipesList;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_recipes_recipe_item, parent, false);
mDatabase = FirebaseDatabase.getInstance().getReference();
mainActivity = (MainActivity) view.getContext();
progressBar = mainActivity.findViewById(R.id.main_progressBar);
return new HomeListAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
final Recipe recipe = mRecipesList.get(position);
SetUserData(holder, position);
holder.tv_recipe_title.setText(mRecipesList.get(position).getTitle());
holder.tv_recipe_prepTime.setText(mRecipesList.get(position).getPrepTime());
Glide.with(context).load(mRecipesList.get(position).getUrl())
.placeholder(R.drawable.ic_loading).thumbnail(0.05f).fitCenter()
.transition(DrawableTransitionOptions.withCrossFade()).centerCrop()
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
.into(holder.recipe_thumbnail);
Log.i(TAG, "onBindViewHolder: Database Reference = " + mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid()).child(Constants.DATABASE_ROOT_LIKES));
mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid()).child(Constants.DATABASE_ROOT_LIKES).addValueEventListener(new ValueEventListener() {
#SuppressLint("SetTextI18n")
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
likeCounter = (int) dataSnapshot.getChildrenCount();
Log.i(TAG, "onDataChange: ChildrenCount = " + recipe.getTitle() + " " + likeCounter);
holder.tv_like_counter.setText(Integer.toString(likeCounter));
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid())
.child(Constants.DATABASE_ROOT_LIKES).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.hasChild(getUid())){
holder.like.setLiked(true);
Log.i(TAG, "onDataChange: LIKED RECIPE...");
}else{
Log.i(TAG, "onDataChange: RECIPE IS NOT LIKED...");
holder.like.setLiked(false);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid())
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.hasChild(Constants.DATABASE_RECIPE_LIKE_COUNT_VALUE)){
holder.tv_like_counter.setText(String.valueOf(dataSnapshot.child(Constants.DATABASE_RECIPE_LIKE_COUNT_VALUE).getValue()));
}else{
holder.tv_like_counter.setText("0");
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
holder.like.setOnLikeListener(new OnLikeListener() {
#Override
public void liked(LikeButton likeButton) {
Log.i(TAG, "liked: LIKED");
// Add like
holder.like.setLiked(true);
Log.i(TAG, "CheckLikeStatus: " + recipe.title + " " + recipe.hasLiked);
mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid()).child(Constants.DATABASE_ROOT_LIKES).child(getUid()).setValue("true");
}
#Override
public void unLiked(LikeButton likeButton) {
Log.i(TAG, "unLiked: UNLIKED");
// remove Like
holder.like.setLiked(false);
Log.i(TAG, "CheckLikeStatus: " + recipe.title + " " + recipe.hasLiked);
mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid()).child(Constants.DATABASE_ROOT_LIKES).child(getUid()).removeValue();
}
});
}
private void SetUserData(ViewHolder holder, int position) {
mDatabase.child(Constants.DATABASE_ROOT_USERS).child(mRecipesList.get(position).getCreatorId())
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
holder.tv_user_username.setText(user.getUsername());
Glide.with(context).load(user.getUrl()).centerCrop().placeholder(R.drawable.ic_loading).into(holder.userPhoto);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#Override
public int getItemCount() {
return mRecipesList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView tv_recipe_title, tv_recipe_prepTime, tv_user_username, tv_like_counter;
public ImageView recipe_thumbnail;
public LikeButton like;
public CircleImageView userPhoto;
public LinearLayout user_ll;
public FirebaseAuth mAuth;
public FirebaseDatabase mDatabase;
public ViewHolder(#NonNull View itemView) {
super(itemView);
mainActivity = (MainActivity) itemView.getContext();
mDatabase = FirebaseDatabase.getInstance();
tv_recipe_title = itemView.findViewById(R.id.recipe_item_title);
tv_recipe_prepTime = itemView.findViewById(R.id.recipe_item_time);
recipe_thumbnail = itemView.findViewById(R.id.recipe_item_photo);
like = itemView.findViewById(R.id.recipe_item_image_like);
tv_like_counter = itemView.findViewById(R.id.recipe_item_like_counter);
userPhoto = itemView.findViewById(R.id.recipe_item_user_photo);
tv_user_username = itemView.findViewById(R.id.recipe_item_user_username);
user_ll = itemView.findViewById(R.id.recipe_item_user_linearLayout);
user_ll.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ProfileFragment pf = new ProfileFragment();
if(pf.isAdded()){
return;
}else{
Bundle bundle = new Bundle();
bundle.putString(Constants.EXTRA_USER_UID,mRecipesList.get(getAdapterPosition()).getCreatorId());
Log.i(TAG, "onClick: Fragment Interaction recipe Creator Id = " + mRecipesList.get(getAdapterPosition()).getCreatorId());
FragmentTransaction ft = mainActivity.getSupportFragmentManager().beginTransaction();
pf.setArguments(bundle);
ft.replace(R.id.main_frame, pf, Constants.FRAGMENT_TAG_PROFILE);
ft.addToBackStack(Constants.FRAGMENT_TAG_PROFILE);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
}
});
itemView.setOnClickListener(v -> {
RecipeDetailsFragment rd = new RecipeDetailsFragment();
if(rd.isAdded()){
return;
}else{
Bundle bundle = new Bundle();
bundle.putString(Constants.EXTRA_RECIPE_KEY,mRecipesList.get(getAdapterPosition()).getUid());
bundle.putString(Constants.EXTRA_RECIPE_CREATOR_ID, mRecipesList.get(getAdapterPosition()).getCreatorId());
Log.i(TAG, "onClick: Fragment Interaction recipe Key is = " + mRecipesList.get(getAdapterPosition()).getUid());
FragmentTransaction ft = mainActivity.getSupportFragmentManager().beginTransaction();
rd.setArguments(bundle);
ft.replace(R.id.main_frame, rd, Constants.FRAGMENT_TAG_RECIPE_DETAILS);
ft.addToBackStack(null);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
});
}
}
public String getUid() {
return FirebaseAuth.getInstance().getCurrentUser().getUid();
}
}

So, after checking the logs, it is very clear that there is nothing wrong with the Firebase. But, there is something wrong with your view binding process with the adapter. The tutorials which you are following right now, is not going to help, since everything is okay on the firebase side.
The problem is, that when you are calling
holder.tv_like_counter.setText(Integer.toString(likeCounter)); ,
tv_like_counter is not even prepared yet.
It would be great if you can show how you are binding your views in the adapter. If not, you can also refer this link to solve your problem. At Least now you know in which direction you need to search ;)

I did a bit more of a different perspective look after checking the view bindings. I found that there was a contradiction. See below:
mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid())
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.hasChild(Constants.DATABASE_RECIPE_LIKE_COUNT_VALUE)){
holder.tv_like_counter.setText(String.valueOf(dataSnapshot.child(Constants.DATABASE_RECIPE_LIKE_COUNT_VALUE).getValue()));
}else{
// likes do not exist
holder.tv_like_counter.setText("0");
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
I removed holder.tv_like_counter.setText("0");. It's supposed to only set it to 0 if the snapshot didn't have the child. I simply forgot the logic I had in place when I was troubleshooting.

Don't do fetching data from database operation inside the onBindViewHolder, It is a very bad practice and data calls will be created every time when the view comes to display.
And it won't be completed that's why you did not get the output. because before getting output it may be destroyed.
Do whole data related operations inside your Activity and pass the
data to Adapter.
See this
Happy coding !!!

Related

Recyclerview won't show items, Firebase Admin SDK, Realtime Database

I'm trying to retrieve some simple data from my database as an Admin, the data has been retrieved, but nothing is shown on the recyclerview.
In the other hand, i was trying to assign a value (String) from the database to a TextView, i was recieving the value, but the TextView was empty, i went to the .xml file and changed the layout_width from android:layout_width="wrap_content" to android:layout_width="match_parent" and it worked! Before that with the simple Firebase Client SDK it was showing the texte even with android:layout_width="wrap_content"
PS: Since i started using the Firebase Admin SDK, I didn't had any issues with writing data to the Realtime database, Or with creating Users. I tried both of them and they works fine.
Here's the retrieving function :
private void RetriveClasses() {
// Get a reference to our posts
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("Classrooms");
mclassrooms.clear();
// Attach a listener to read the data at our posts reference
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren())
{
Classroom post = snapshot.getValue(Classroom.class);
if (!post.getDeleted().equals("true"))
{
mclassrooms.add(post);
}
mAdapter.notifyDataSetChanged();
System.out.println(post.getClassName());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
}
The System.out.println(post.getClassName()); Shows :
I/System.out: L1 ST 2022-2023
L1 ST 2021-2022
L1 ST 2015-2016
These are the class names i'm looking for, which means the reading is succeed, but the recyclerview still won't show any items.
here's my Adapter:
public class ClassroomsAdapter extends RecyclerView.Adapter<ClassroomsAdapter.ViewHolder> {
private Context c;
public List<Classroom> mclassrooms;
public ClassroomsAdapter(List<Classroom> mclassrooms) {
this.mclassrooms = mclassrooms;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
this.c = parent.getContext();
View view = LayoutInflater.from(c).inflate(R.layout.classroom_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
final Classroom classroom = mclassrooms.get(position);
if (classroom.getClassName().length() >= 20)
{
String className = classroom.getClassName();
holder.classroom_name.setText(className.substring(0,19) + "...");
}
else
{
holder.classroom_name.setText(classroom.getClassName());
}
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
final BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(c, R.style.BottomSheetDialogTheme);
View eview = LayoutInflater.from(c).inflate(R.layout.bottom_menu_classroom, null);
eview.findViewById(R.id.Delete_Comment_Btn).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final ProgressDialog progressDialog = new ProgressDialog(c, R.style.MyAlertDialogStyle);
progressDialog.setTitle("Suppression");
progressDialog.setMessage("Traitement...");
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.show();
DatabaseReference mRoot = FirebaseDatabase.getInstance().getReference("Classrooms");
mRoot.child(classroom.getClassId()).child("deleted").setValue("true", new DatabaseReference.CompletionListener(){
#Override
public void onComplete(DatabaseError error, DatabaseReference ref) {
progressDialog.dismiss();
Toast.makeText(c, "Suppression avec succès!", Toast.LENGTH_SHORT).show();
bottomSheetDialog.dismiss();
}
});
}
});
eview.findViewById(R.id.copy_comment_button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final BottomSheetDialog bs = new BottomSheetDialog(c, R.style.BottomSheetDialogTheme);
View aview = LayoutInflater.from(c).inflate(R.layout.edit_class_name, null);
EditText name_et = aview.findViewById(R.id.Edition_Comment_Input_Field);
name_et.setText(classroom.getClassName());
aview.findViewById(R.id.update_comment).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (name_et.getText().toString().isEmpty()) {
Toast.makeText(c, "Ce champ est requis*", Toast.LENGTH_SHORT).show();
} else {
final ProgressDialog progressDialog = new ProgressDialog(c, R.style.MyAlertDialogStyle);
progressDialog.setTitle("Mise à jour");
progressDialog.setMessage("Traitement...");
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.show();
DatabaseReference mRoot = FirebaseDatabase.getInstance().getReference("Classrooms");
mRoot.child(classroom.getClassId()).child("className").setValue(name_et.getText().toString(), new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError error, DatabaseReference ref) {
progressDialog.dismiss();
Toast.makeText(c, "Mise à jour avec succès!", Toast.LENGTH_SHORT).show();
bs.dismiss();
bottomSheetDialog.dismiss();
}
});
}
}
});
aview.findViewById(R.id.close_edit_comment).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
bs.dismiss();
}
});
bs.setContentView(aview);
bs.show();
}
});
bottomSheetDialog.setContentView(eview);
bottomSheetDialog.show();
return false;
}
});
}
#Override
public int getItemCount() {
return mclassrooms.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView classroom_name;
public ViewHolder(#NonNull View itemView) {
super(itemView);
classroom_name = itemView.findViewById(R.id.class_name);
}
}
}
Thanks for your time.

Why does the recyclerview data loads only when the button is clicked the second time

I am developing an app based on placement. I have used firebase realtime database for this. I am matching company name from the "Job Post" db and "Applied Candidate" db, so that only applied candidates detail for that particular company will be displayed. Everything is working fine but the issue is the recyclerview's data loads only when the button is clicked the second time.
public class AppliedCandidateActivity extends AppCompatActivity {
Toolbar toolbarAppliedcandidate;
RecyclerView rvAppliedCandidate;
List<appliedData> ls;
String compNameposted;
AppCandidateAdapter adapter;
DatabaseReference dbJobPost,dbAppliedCandidate;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.applied_candidate);
toolbarAppliedcandidate = findViewById(R.id.toolbarAppliedcandidate);
rvAppliedCandidate = findViewById(R.id.rvAppliedCandidate);
setSupportActionBar(toolbarAppliedcandidate);
getSupportActionBar().setTitle("Applied Candidate");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
rvAppliedCandidate.setHasFixedSize(true);
rvAppliedCandidate.setLayoutManager(new LinearLayoutManager(this));
ls = new ArrayList<>();
adapter = new AppCandidateAdapter(getApplicationContext(),ls);
rvAppliedCandidate.setAdapter(adapter);
getCompany();
matchCompanyName();
}
void getCompany()
{
//To retrieve company name
dbJobPost = FirebaseDatabase.getInstance().getReference("Job Post").child(FirebaseAuth.getInstance().getCurrentUser().getUid());
dbJobPost.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot ds : snapshot.getChildren())
{
PostJobData postJobData = ds.getValue(PostJobData.class);
compNameposted = postJobData.getCompName().toString();
//Toast.makeText(getApplicationContext(),postJobData.getCompName(),Toast.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
void matchCompanyName()
{
//To retrieve data of applied candidate for particular company
dbAppliedCandidate = FirebaseDatabase.getInstance().getReference("Applied Candidate");
dbAppliedCandidate.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot ds: snapshot.getChildren())
{
for (DataSnapshot ds1 : ds.getChildren())
{
appliedData data = ds1.getValue(appliedData.class);
String compName = data.getCompName().toString();
//Toast.makeText(getApplicationContext(),compName,Toast.LENGTH_LONG).show();
if(compName.equals(compNameposted))
{
ls.add(data);
}
else if(ls.isEmpty()== true){
Toasty.info(AppliedCandidateActivity.this,"No One Applied Yet!!",Toast.LENGTH_LONG,true).show();
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
public class AppCandidateAdapter extends RecyclerView.Adapter<AppCandidateAdapter.AppCandidateViewHolder>{
List<appliedData> appliedDataList;
Context context;
public AppCandidateAdapter(Context mcontext,List list){
this.context = mcontext;
this.appliedDataList = list;
}
#NonNull
#Override
public AppCandidateViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.applied_candidate_compside,parent,false);
return new AppCandidateViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull AppCandidateViewHolder holder, int position) {
appliedData data = appliedDataList.get(position);
holder.tvCandidateName.setText(data.getName());
holder.tvCandidateAppliedPost.setText(data.getPosition());
holder.tvCandidateQual.setText(data.getQualification());
holder.tvCandidateSkills.setText(data.getSkills());
}
#Override
public int getItemCount() {
return appliedDataList.size();
}
class AppCandidateViewHolder extends RecyclerView.ViewHolder{
TextView tvCandidateName,tvCandidateAppliedPost,tvCandidateQual,tvCandidateSkills;
Button btnDeleteCandidate,btnSendMail;
public AppCandidateViewHolder(#NonNull View itemView) {
super(itemView);
tvCandidateName = itemView.findViewById(R.id.tvCandidateName);
tvCandidateAppliedPost = itemView.findViewById(R.id.tvCandidateAppliedPost);
tvCandidateQual = itemView.findViewById(R.id.tvCandidateQual);
tvCandidateSkills = itemView.findViewById(R.id.tvCandidateSkills);
btnDeleteCandidate = itemView.findViewById(R.id.btnDeleteCandidate);
btnSendMail = itemView.findViewById(R.id.btnSendMail);
}
}
}
}
Assuming your onDataChange does get called, successfully reads the PostJobData data from the snapshot, and adds it to ls, you're not telling Android that the list has changed. Only once you notify the adapter of the change, will it rerender the view.
dbJobPost = FirebaseDatabase.getInstance().getReference("Job Post").child(FirebaseAuth.getInstance().getCurrentUser().getUid());
dbJobPost.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot ds : snapshot.getChildren()) {
PostJobData postJobData = ds.getValue(PostJobData.class);
compNameposted = postJobData.getCompName().toString();
}
adapter.notifyDataSetChanged(); // notify the adapter
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException(); // never ignore errors
}
});

How to show multiple random childs from Firebase Realtime Database

I am trying to show random users from Firebase Realtime Database .I am currently able to show one random user from my Firebase Realtime database but what i want to do is show 6 random users on to my recyclerview at once .But i am unable to figure out how to add query for same without getting an error at runtime.
Mycode
public class UsersFragment extends Fragment {
private RecyclerView recyclerView;
private UserAdapter mUserAdapter;
private List<User> mUsers;
String TAG = "MyTag";
ValueEventListener mValueEventListener;
List<String> UserIdsList = new ArrayList<>();
public UsersFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_users, container, false);
recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mUsers = new ArrayList<>();
//readUser();
RandomUsers();
return view;
}
private void RandomUsers() {
//mUsers.add((User) UserIdsList);
mUserAdapter = new UserAdapter(getContext(), mUsers, false);
recyclerView.setAdapter(mUserAdapter);
mUserAdapter.notifyDataSetChanged();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference UserIdsRef = rootRef.child("UserIds");
ValueEventListener mValueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String userIDS = ds.getKey();
UserIdsList.add(userIDS);
}
int UserListSize = UserIdsList.size();
Log.d(TAG, String.valueOf(UserListSize));
Random random=new Random();
int random1=random.nextInt(UserListSize);
// int Rdm= UserIdsList.get(new Random().nextInt(UserListSize));
DatabaseReference UserRef = rootRef.child("Users").child(UserIdsList.get(random1));
Log.d(TAG,"UserRef "+ String.valueOf(UserRef));
//new Random().nextInt(UserListSize)
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
mUsers.add(user);
mUserAdapter.notifyDataSetChanged();
String name = dataSnapshot.child("First").getValue(String.class);
Log.d(TAG, "Name called "+name);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, "Error: " + databaseError.toException()); //Don't ignore errors!
}
};
UserRef.addListenerForSingleValueEvent(eventListener);
//UserRef.addValueEventListener(eventListener);
Query query2 = UserRef.limitToFirst(2);
query2.addListenerForSingleValueEvent(eventListener);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, "Error: " + databaseError.getMessage()); //Don't ignore errors!
}
};
UserIdsRef.addListenerForSingleValueEvent(mValueEventListener);
//UserIdsRef.addValueEventListener(mValueEventListener);
}
}
UserAdapter.java
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder> {
private Context mContext;
private List<User> mUsers;
private List<String> UserIdsList;
private boolean ischat;
String theLastMessage;
public UserAdapter(Context mContext, List<User> mUsers,boolean ischat) {
this.mContext = mContext;
this.mUsers = mUsers;
this.ischat=ischat;
}
#NonNull
#Override
public UserAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(mContext).inflate(R.layout.user_item,parent,false);
return new UserAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull UserAdapter.ViewHolder holder, int position) {
final User user=mUsers.get(position);
holder.username.setText(user.getFirst());
if (user.getImageURL().equals("default")){
holder.profile_image.setImageResource(R.mipmap.ic_launcher);
} else {
Glide.with(mContext).load(user.getImageURL()).into(holder.profile_image);
}
if (ischat){
lastMessage(user.getId(), holder.last_msg);
} else {
holder.last_msg.setVisibility(View.GONE);
}
if (ischat){
if (user.getStatus().equals("online")){
holder.img_on.setVisibility(View.VISIBLE);
holder.img_off.setVisibility(View.GONE);
} else {
holder.img_on.setVisibility(View.GONE);
holder.img_off.setVisibility(View.VISIBLE);
}
} else {
holder.img_on.setVisibility(View.GONE);
holder.img_off.setVisibility(View.GONE);
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent=new Intent(mContext, MessageActivity.class);
intent.putExtra("UserName",user.getFirst());
intent.putExtra("userid", user.getId());
intent.putExtra("ImageURL",user.getImageURL());
mContext.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return mUsers.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView username;
public ImageView profile_image;
private ImageView img_on;
private ImageView img_off;
private TextView last_msg;
public ViewHolder(#NonNull View itemView) {
super(itemView);
username=itemView.findViewById(R.id.username);
profile_image=itemView.findViewById(R.id.profile_image);
img_on = itemView.findViewById(R.id.img_on);
img_off = itemView.findViewById(R.id.img_off);
last_msg=itemView.findViewById(R.id.last_msg);
}
}
private void lastMessage(final String userid, final TextView last_msg){
theLastMessage = "default";
final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Chats");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Chat chat = snapshot.getValue(Chat.class);
if (firebaseUser != null && chat != null) {
if (chat.getReceiver().equals(firebaseUser.getUid()) && chat.getSender().equals(userid) ||
chat.getReceiver().equals(userid) && chat.getSender().equals(firebaseUser.getUid())) {
theLastMessage = chat.getMessage();
}
}
}
switch (theLastMessage){
case "default":
last_msg.setText("No Message");
break;
default:
last_msg.setText(theLastMessage);
break;
}
theLastMessage = "default";
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Data Snapshot
DataSnapshot { key = KRhmaWXCctMHbU1Z6NAWRGGw2ag2, value = {EmailId=abc#gmail.com, First=shivam} }
You can try this:
DatabaseReference UserRef = rootRef.child("Users").orderByKey().startAt(UserIdsList.get(random1)).lim‌​itToFirst(6);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
mUsers.add(user);
mUserAdapter.notifyDataSetChanged();
String name = dataSnapshot.child("First").getValue(String.class);
Log.d(TAG, "Name called "+name);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, "Error: " + databaseError.toException());
}
};
UserRef.addListenerForSingleValueEvent(eventListener);

Recyclerview adding multiple items when only one was added

Firstly, I've looked into the existing questions that discuss similar issues as mine. Primarily this answer is the closet to the issue I'm having --> Link. I didn't see any solutions that fit my issue.
I've attached below the code for both my HomeFragment & HomeListAdapter. I've done some research as some say I shouldn't do the firebase database calls within the bindviewholder, but Firebase quick start database example is what I am following so if any firebase android engineers might give me some direction that would be great.
When I click add on my Edit Recipe Fragment. After the upload has completed it goes to the home fragment. The confusion I have is every other adapter I have in the app has the correct behavior. It only adds one recipe (only one is ever added at a time is the expected behavior).
HomeFragment
package com.irondigitalmedia.keep;
import java.util.ArrayList;
public class HomeFragment extends BaseFragment {
private static final String TAG = HomeFragment.class.getSimpleName();
private ArrayList<Recipe> mRecipeList;
private ArrayList<String> mRecipeIds;
private RecyclerView HomeRecyclerView;
private HomeListAdapter adapter;
private LinearLayoutManager LLM;
private Context mContext;
private FirebaseDatabase database;
private DatabaseReference myRef;
private Recipe mRecipe;
private User mUser;
private int likeCounter = 0;
private MainActivity mainActivity;
private BaseActivity baseActivity;
private Toolbar toolbar;
private ProgressBar progressBar;
public HomeFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home,container,false);
mContext = view.getContext();
mRecipeList = new ArrayList<>();
mRecipeIds = new ArrayList<>();
HomeRecyclerView = view.findViewById(R.id.frag_search_rv);
HomeRecyclerView.addItemDecoration(new SpacesItemDecoration(8));
LLM = new LinearLayoutManager(getContext());
HomeRecyclerView.setLayoutManager(LLM);
adapter = new HomeListAdapter(mContext, mRecipeList, mUser);
HomeRecyclerView.setAdapter(adapter);
mainActivity = (MainActivity) view.getContext();
mainActivity.mMainNav.setSelectedItemId(R.id.nav_home);
toolbar = mainActivity.findViewById(R.id.main_toolbar);
toolbar.setTitle("Home");
mainActivity.setSupportActionBar(toolbar);
if(savedInstanceState != null){
Log.e(TAG, "onCreateView: savedInstanceState is null");
}else{
LoadRecipes();
}
return view;
}
private void LoadRecipes() {
database = FirebaseDatabase.getInstance();
myRef = database.getReference();
myRef.child(Constants.DATABASE_ROOT_FOLLOWING).child(getUid()).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
String key = dataSnapshot.getKey();
Log.i(TAG, "onChildAdded: key is = " + key);
if(key!=null){
Log.i(TAG, "onChildAdded: key is not null ");
myRef.child(Constants.DATABASE_ROOT_USERS_RECIPES).child(key).limitToFirst(5).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
// A new comment has been added, add it to the displayed list
mRecipe = dataSnapshot.getValue(Recipe.class);
// [START_EXCLUDE]
// Update RecyclerView
mRecipeIds.add(dataSnapshot.getKey());
mRecipeList.add(mRecipe);
adapter.notifyItemInserted(mRecipeList.size() - 1);
// [END_EXCLUDE]
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());
// A comment has changed, use the key to determine if we are displaying this
// comment and if so displayed the changed comment.
mRecipe = dataSnapshot.getValue(Recipe.class);
String recipeKey = dataSnapshot.getKey();
// [START_EXCLUDE]
int commentIndex = mRecipeIds.indexOf(recipeKey);
if (commentIndex > -1) {
// Replace with the new data
mRecipeList.set(commentIndex, mRecipe);
// Update the RecyclerView
adapter.notifyItemChanged(commentIndex);
} else {
Log.w(TAG, "onChildChanged:unknown_child:" + recipeKey);
}
// [END_EXCLUDE]
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());
// A comment has changed, use the key to determine if we are displaying this
// comment and if so remove it.
String recipeKey = dataSnapshot.getKey();
// [START_EXCLUDE]
int commentIndex = mRecipeIds.indexOf(recipeKey);
if (commentIndex > -1) {
// Remove data from the list
mRecipeIds.remove(commentIndex);
mRecipeList.remove(commentIndex);
// Update the RecyclerView
adapter.notifyItemRemoved(commentIndex);
} else {
Log.w(TAG, "onChildRemoved:unknown_child:" + recipeKey);
}
// [END_EXCLUDE]
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());
// A comment has changed position, use the key to determine if we are
// displaying this comment and if so move it.
mRecipe = dataSnapshot.getValue(Recipe.class);
String recipeKey = dataSnapshot.getKey();
// ...
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "recipes:onCancelled", databaseError.toException());
Toast.makeText(mContext, "Failed to load recipes.",
Toast.LENGTH_SHORT).show();
}
});
}else{
Log.e(TAG, "onChildAdded: Key is null");
}
}
#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 onSaveInstanceState(#NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList(Constants.SAVED_STATE_HOME,mRecipeList);
}
#Override
public void onStart() {
super.onStart();
getActivity().setTitle("Home");
}
public String getUid() {
return FirebaseAuth.getInstance().getCurrentUser().getUid();
}
}
HomeListAdapter
package com.irondigitalmedia.keep.Adapters;
public class HomeListAdapter extends RecyclerView.Adapter<HomeListAdapter.ViewHolder> {
private static final String TAG = HomeListAdapter.class.getSimpleName();
private DatabaseReference mDatabase;
private Context context;
private List<Recipe> mRecipesList;
private MainActivity mainActivity;
private User user;
private int likeCounter = 0;
public HomeListAdapter(Context context, List<Recipe> mRecipesList, User user) {
this.context = context;
this.mRecipesList = mRecipesList;
this.user = user;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_recipes_recipe_item, parent, false);
mDatabase = FirebaseDatabase.getInstance().getReference();
mainActivity = (MainActivity) view.getContext();
return new HomeListAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
final Recipe recipe = mRecipesList.get(position);
SetUserData(holder, position);
holder.tv_recipe_title.setText(mRecipesList.get(position).getTitle());
holder.tv_recipe_prepTime.setText(mRecipesList.get(position).getPrepTime());
Glide.with(context).load(mRecipesList.get(position).getUrl())
.placeholder(R.drawable.ic_loading).thumbnail(0.05f).fitCenter()
.transition(DrawableTransitionOptions.withCrossFade()).centerCrop()
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
.into(holder.recipe_thumbnail);
Log.i(TAG, "onBindViewHolder: Database Reference = " +
mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid()).child(Constants.DATABASE_ROOT_LIKES));
mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid())
.child(Constants.DATABASE_ROOT_LIKES).addValueEventListener(new ValueEventListener() {
#SuppressLint("SetTextI18n")
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
likeCounter = (int) dataSnapshot.getChildrenCount();
Log.i(TAG, "onDataChange: ChildrenCount = " + recipe.getTitle() + " " + likeCounter);
holder.tv_like_counter.setText(Integer.toString(likeCounter));
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid())
.child(Constants.DATABASE_ROOT_LIKES).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.hasChild(getUid())){
holder.like.setLiked(true);
Log.i(TAG, "onDataChange: LIKED RECIPE...");
}else{
Log.i(TAG, "onDataChange: RECIPE IS NOT LIKED...");
holder.like.setLiked(false);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid())
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.hasChild(Constants.DATABASE_RECIPE_LIKE_COUNT_VALUE)){
holder.tv_like_counter.setText(String.valueOf(dataSnapshot.child(Constants.DATABASE_RECIPE_LIKE_COUNT_VALUE).getValue()));
}else{
// likes do not exist
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
holder.like.setOnLikeListener(new OnLikeListener() {
#Override
public void liked(LikeButton likeButton) {
Log.i(TAG, "liked: LIKED");
// Add like
holder.like.setLiked(true);
mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid()).child(Constants.DATABASE_ROOT_LIKES).child(getUid()).setValue("true");
}
#Override
public void unLiked(LikeButton likeButton) {
Log.i(TAG, "unLiked: UNLIKED");
// remove Like
holder.like.setLiked(false);
mDatabase.child(Constants.DATABASE_ROOT_RECIPES).child(recipe.getUid()).child(Constants.DATABASE_ROOT_LIKES).child(getUid()).removeValue();
}
});
}
private void SetUserData(ViewHolder holder, int position) {
mDatabase.child(Constants.DATABASE_ROOT_USERS).child(mRecipesList.get(position).getCreatorId())
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
holder.tv_user_username.setText(user.getUsername());
Glide.with(context).load(user.getUrl()).centerCrop().placeholder(R.drawable.ic_loading).into(holder.userPhoto);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#Override
public int getItemCount() {
return mRecipesList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView tv_recipe_title, tv_recipe_prepTime, tv_user_username, tv_like_counter;
public ImageView recipe_thumbnail;
public LikeButton like;
public CircleImageView userPhoto;
public LinearLayout user_ll;
public FirebaseAuth mAuth;
public FirebaseDatabase mDatabase;
public ViewHolder(#NonNull View itemView) {
super(itemView);
mainActivity = (MainActivity) itemView.getContext();
mDatabase = FirebaseDatabase.getInstance();
tv_recipe_title = itemView.findViewById(R.id.recipe_item_title);
tv_recipe_prepTime = itemView.findViewById(R.id.recipe_item_time);
recipe_thumbnail = itemView.findViewById(R.id.recipe_item_photo);
like = itemView.findViewById(R.id.recipe_item_image_like);
tv_like_counter = itemView.findViewById(R.id.recipe_item_like_counter);
userPhoto = itemView.findViewById(R.id.recipe_item_user_photo);
tv_user_username = itemView.findViewById(R.id.recipe_item_user_username);
user_ll = itemView.findViewById(R.id.recipe_item_user_linearLayout);
user_ll.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ProfileFragment pf = new ProfileFragment();
if(pf.isAdded()){
return;
}else{
Bundle bundle = new Bundle();
bundle.putString(Constants.EXTRA_USER_UID,mRecipesList.get(getAdapterPosition()).getCreatorId());
Log.i(TAG, "onClick: Fragment Interaction recipe Creator Id = " + mRecipesList.get(getAdapterPosition()).getCreatorId());
FragmentTransaction ft = mainActivity.getSupportFragmentManager().beginTransaction();
pf.setArguments(bundle);
ft.replace(R.id.main_frame, pf, Constants.FRAGMENT_TAG_PROFILE);
ft.addToBackStack(Constants.FRAGMENT_TAG_PROFILE);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
}
});
itemView.setOnClickListener(v -> {
RecipeDetailsFragment rd = new RecipeDetailsFragment();
if(rd.isAdded()){
return;
}else{
Bundle bundle = new Bundle();
bundle.putString(Constants.EXTRA_RECIPE_KEY,mRecipesList.get(getAdapterPosition()).getUid());
bundle.putString(Constants.EXTRA_RECIPE_CREATOR_ID, mRecipesList.get(getAdapterPosition()).getCreatorId());
Log.i(TAG, "onClick: Fragment Interaction recipe Key is = " + mRecipesList.get(getAdapterPosition()).getUid());
FragmentTransaction ft = mainActivity.getSupportFragmentManager().beginTransaction();
rd.setArguments(bundle);
ft.replace(R.id.main_frame, rd, Constants.FRAGMENT_TAG_RECIPE_DETAILS);
ft.addToBackStack(null);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
});
}
}
public String getUid() {
return FirebaseAuth.getInstance().getCurrentUser().getUid();
}
}
EditRecipeFragment
package com.irondigitalmedia.keep.Adapters;
public class EditIngredientAdapter extends RecyclerView.Adapter<EditIngredientAdapter.IngredientViewHolder> {
private static final String TAG = EditIngredientAdapter.class.getSimpleName();
private String dataSnapShotKey;
private Context mContext;
private DatabaseReference mDatabaseReference;
private ChildEventListener mChildEventListener;
public List<String> mIngredientIds = new ArrayList<>();
public List<Ingredient> mIngredients = new ArrayList<>();
public EditIngredientAdapter(final Context mContext, DatabaseReference ref) {
this.mContext = mContext;
this.mDatabaseReference = ref;
// Create child event listener
// [START child_event_listener_recycler]
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
dataSnapShotKey = dataSnapshot.getKey();
// A new comment has been added, add it to the displayed list
Ingredient ingredient = dataSnapshot.getValue(Ingredient.class);
// [START_EXCLUDE]
// Update RecyclerView
mIngredientIds.add(dataSnapshot.getKey());
mIngredients.add(ingredient);
notifyItemInserted(mIngredients.size() - 1);
// [END_EXCLUDE]
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());
// A comment has changed, use the key to determine if we are displaying this
// comment and if so displayed the changed comment.
Ingredient newIngredient = dataSnapshot.getValue(Ingredient.class);
String ingredientKey = dataSnapshot.getKey();
// [START_EXCLUDE]
int ingredientIndex = mIngredientIds.indexOf(ingredientKey);
if (ingredientIndex > -1) {
// Replace with the new data
mIngredients.set(ingredientIndex, newIngredient);
// Update the RecyclerView
notifyItemChanged(ingredientIndex);
} else {
Log.w(TAG, "onChildChanged:unknown_child:" + ingredientKey);
}
// [END_EXCLUDE]
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());
// A comment has changed, use the key to determine if we are displaying this
// comment and if so remove it.
String ingredientKey = dataSnapshot.getKey();
// [START_EXCLUDE]
int ingredientIndex = mIngredientIds.indexOf(ingredientKey);
if (ingredientIndex > -1) {
// Remove data from the list
mIngredientIds.remove(ingredientIndex);
mIngredients.remove(ingredientIndex);
// Update the RecyclerView
notifyItemRemoved(ingredientIndex);
} else {
Log.w(TAG, "onChildRemoved:unknown_child:" + ingredientKey);
}
// [END_EXCLUDE]
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());
// A comment has changed position, use the key to determine if we are
// displaying this comment and if so move it.
Ingredient movedIngredient = dataSnapshot.getValue(Ingredient.class);
String ingredientKey = dataSnapshot.getKey();
// ...
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "postComments:onCancelled", databaseError.toException());
Toast.makeText(mContext, "Failed to load comments.",
Toast.LENGTH_SHORT).show();
}
};
ref.addChildEventListener(childEventListener);
// [END child_event_listener_recycler]
// Store reference to listener so it can be removed on app stop
mChildEventListener = childEventListener;
}
#NonNull
#Override
public IngredientViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.list_item_recipe_ingredient, parent, false);
return new IngredientViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull IngredientViewHolder holder, int position) {
Ingredient ingredient = mIngredients.get(position);
holder.ingred.setText(ingredient.ingredient);
}
#Override
public int getItemCount() {
return mIngredients.size();
}
public class IngredientViewHolder extends RecyclerView.ViewHolder {
public TextView ingred;
public IngredientViewHolder(View itemView) {
super(itemView);
ingred = itemView.findViewById(R.id.recipe_ingredients_tv);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext, "Ingredient: " + mIngredients.get(getAdapterPosition()).ingredient, Toast.LENGTH_SHORT).show();
}
});
itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Toast.makeText(mContext, "Long Clicked " + getAdapterPosition(), Toast.LENGTH_SHORT).show();
return true;
}
});
}
}
public void RemoveIngredient(DatabaseReference reference){
reference.removeValue();
}
public void cleanupListener() {
if (mChildEventListener != null) {
mDatabaseReference.removeEventListener(mChildEventListener);
}
}
}
Screenshots:
Go To Search and back to home
Back to home
Attempted solution from Majuran (thank you), but it didn't work. Same result. When adding the list.clear() method to both lists.
In my understanding, One thing is added again in your view. when you come back to the same fragment right? (I got the same issue in my last project)
The problem is in HomeFragment. Same values are adding again in your these lists.
mRecipeList = new ArrayList<>();
mRecipeIds = new ArrayList<>();
so clear it, before adding the listener
myRef = database.getReference();
mRecipeList.clear();
mRecipeIds.clear();
myRef.child(Constants.DATABASE_ROOT_FOLLOWING).child(getUid()).add...
Hope its helpful, Happy coding!!!
I was able to resolve this by putting the database call inside the constructor of the adapter. This is the same practice that is within the example that the firebase team put inside their database example app.

Accessing a child within a child firebase

This is not a duplicate.
I am trying to access a child within a child in firebase and then putting that child into a recycler adapter. It won't show in the recycler adapter. There is a similar question on here to this but when implementing it, it still doesn't work.
Currently using an adapter, a messages object and a fragment.
Fragment Activity
private ArrayList<Messages> results = new ArrayList<>();
private void listenForChat() {
final DatabaseReference userDb = FirebaseDatabase.getInstance().getReference().child("users").child(currentUid)
.child("receivedMessages");
messageUrlDb = userDb.child("messageUrl");
messageUrlDb.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String message = "";
if (dataSnapshot.child("messageUrl").getValue() != null)
message = dataSnapshot.child("messageUrl").getValue().toString();
Messages obj = new Messages(message, name, image);
if (!results.contains(obj)) {
results.add(obj);
messagesList.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
initializeDisplay();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) { }
});
}
public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ChatViewHolders> {
private List<Messages> mMessageList;
private List<UserObject> usersList;
private Context context;
private DisplayTextFragment displayTextFragment;
private String message;
public ChatAdapter(List<Messages> mMessageList, Context context) {
this.mMessageList = mMessageList;
this.context = context;
}
#Override
public ChatViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_layout, null);
ChatViewHolders rcv = new ChatViewHolders(v);
return rcv;
}
#Override
public void onBindViewHolder(final ChatViewHolders holder, int position) {
holder.messageText.setText(mMessageList.get(position).getMessage());
}
#Override
public int getItemCount() {
return mMessageList.size();
}
public class ChatViewHolders extends RecyclerView.ViewHolder {
public TextView messageText, timeSent, mName;
ImageView mProfile;
LinearLayout mLayout;
public ChatViewHolders(View view) {
super(view);
messageText = (TextView) view.findViewById(R.id.message_text);
mLayout = itemView.findViewById(R.id.layout);
}
}
}
I am trying access (messageUrl) users -> receivedMessages -> messageUrl. However as there is a key they I assume it doesn't as far as messagesUrl. For the recycler adapter it needs take in messagesUrl as a string and update accordingly but I just can't do it.
If any more code is needed I can post. Thank you.
This is how you're attaching your ValueEventListener:
final DatabaseReference userDb = FirebaseDatabase.getInstance().getReference().child("users").child(currentUid)
.child("receivedMessages");
messageUrlDb = userDb.child("messageUrl");
messageUrlDb.addValueEventListener(new ValueEventListener() {
If we take the path from this code, you're attaching the listener to /users/$uid/receivedMessages/messageUrl. This path doesn't exist in the data you showed, so your onDataChanged will get called with an empty snapshot.
If you want to read all messages for the user, you should attach your listener to /users/$uid/receivedMessages and parse the snapshot inside onDataChanged:
final DatabaseReference userDb = FirebaseDatabase.getInstance().getReference().child("users").child(currentUid)
.child("receivedMessages");
userDb.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot userMessages: dataSnapshot.getChildren()) {
for (DataSnapshot messageSnapshot: userMessages.getChildren()) {
System.out.println(messageSnapshot.getKey()+": "+messageSnapshot.getChild("messageUrl").getValue(String.class));
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
This loops over the two level of child nodes you have under the user's receivedMessages node.

Categories

Resources