So I'm trying get my orders listed as users first and then later when clicked taken to the place where all items can be seen. I have set the order ID as the user uid and now I'm trying to get the uid and from that fetch user data. The mykey i have defined as public in starting but I think I'm using it inside loop and hence can't access it outside. Please help
Code I'm trying
firebaseDatabase = FirebaseDatabase.getInstance().getReference().child("Order");
firebaseDatabase.keepSynced(true);
firebaseDatabase2 = FirebaseDatabase.getInstance().getReference().child("Users");
firebaseDatabase.keepSynced(true);
firebaseDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
mykey = snapshot.getKey();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
#Override
protected void onStart() {
super.onStart();
FirebaseRecyclerOptions<Users> options = new FirebaseRecyclerOptions.Builder<Users>().setQuery(firebaseDatabase2.child(mykey), Users.class).build();
FirebaseRecyclerAdapter<Users, Orders.UsersViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Users, Orders.UsersViewHolder>(options)
{
#Override
public Orders.UsersViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.user_layout,parent,false);
return new Orders.UsersViewHolder(view);
}
#Override
protected void onBindViewHolder(Orders.UsersViewHolder holder, int position, Users model) {
holder.setName(model.getName());
holder.setStatus(model.getMobile());
}
};
mylist.setAdapter(firebaseRecyclerAdapter);
firebaseRecyclerAdapter.startListening();
}
public class UsersViewHolder extends RecyclerView.ViewHolder {
View mview;
public UsersViewHolder(#NonNull View itemView) {
super(itemView);
mview = itemView;
}
public void setName(String name) {
TextView userNameView = mview.findViewById(R.id.username);
userNameView.setText(name);
}
public void setStatus(String status) {
TextView userStatusView = mview.findViewById(R.id.phone);
userStatusView.setText(status);
}
}
Related
I am currently trying to create a messaging app.The users who have registered on to my app are showed in users tab but along with those users the user who is currently logged into my app also sees himself in users tab .I don't want user to see himself in users tab.
My code
UserAdapter.java
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder> {
private Context mContext;
private List<User> mUsers;
private boolean ischat;
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){
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());
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;
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);
}
}
}
UsersFragment.java
public class UsersFragment extends Fragment {
private RecyclerView recyclerView;
private UserAdapter mUserAdapter;
private List<User> mUsers;
String TAG = "MyTag";
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();
return view;
}
private void readUser() {
final FirebaseUser firebaseUser=FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference reference= FirebaseDatabase.getInstance().getReference("Users");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mUsers.clear();
for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
User user=snapshot.getValue(User.class);
mUsers.add(user);
}
mUserAdapter=new UserAdapter(getContext(),mUsers,false);
recyclerView.setAdapter(mUserAdapter);
mUserAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Make condition to check if whether current login user is not not equals to the key node then it will add users in array
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mUsers.clear();
for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
if(!FirebaseAuth.getInstance().getCurrentUser().getUid().equals(snapshot.getId())){
User user=snapshot.getValue(User.class);
mUsers.add(user);
}
}
mUserAdapter=new UserAdapter(getContext(),mUsers,false);
recyclerView.setAdapter(mUserAdapter);
mUserAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
I'm quite new to firebase and android world. I want to retrieve only specific groups in which the current logged in user has joined.
Here is my Firebase realtime database structure
However, all the users who logged in are displayed with all the groups exist in the database:
My app screenshot
I tried to filter the output inside the onBindViewHolder method of FirebaseRecylerAdapter but it dont seem to be working :
protected void onBindViewHolder(#NonNull final GroupChatViewHolder holder, final int position, #NonNull Group model) {
final String groups = getRef(position).getKey();
final String retGroupName = groups.toString();
RootRef.child("Groups").child(retGroupName).child("Users").child(currentUser.getUid())
.addValueEventListener(new ValueEventListener() {
#Override
// If current user exist in that group
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
holder.txtGroupName.setText(retGroupName);
// Retrieve groupCreatedBy
RootRef.child("Groups").child(retGroupName).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String retGroupCreatedBy = dataSnapshot.child("groupCreatedBy").getValue().toString();
// Find username of the group creator
RootRef.child("Users").child(retGroupCreatedBy).child("profilename")
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
holder.txtGroupCreatedBy.setText("Group created by: " + dataSnapshot.getValue().toString());
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
Here are my full codes. I implement all the process including the onBindViewHolder in a fragment class as shown below:
public class GroupChatFragment extends Fragment {
private View view;
private RecyclerView chatList;
FirebaseAuth mAuth = FirebaseAuth.getInstance();
FirebaseUser currentUser = mAuth.getCurrentUser();
DatabaseReference RootRef = FirebaseDatabase.getInstance().getReference();
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_group_chat, container, false);
chatList = (RecyclerView) view.findViewById(R.id.group_chat_list);
chatList.setLayoutManager(new LinearLayoutManager(getContext()));
Toolbar toolbar = view.findViewById(R.id.toolbar_chat);
((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
return view;
}
#Override
public void onStart() {
super.onStart();
FirebaseRecyclerOptions<Group> options = new FirebaseRecyclerOptions.Builder<Group>()
.setQuery(RootRef.child("Groups"), Group.class)
.build();
FirebaseRecyclerAdapter<Group, GroupChatViewHolder> adapter =
new FirebaseRecyclerAdapter<Group, GroupChatViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull final GroupChatViewHolder holder, final int position, #NonNull Group model) {
...
}
};
chatList.setAdapter(adapter);
adapter.startListening();
}
public static class GroupChatViewHolder extends RecyclerView.ViewHolder {
TextView txtGroupName, txtGroupCreatedBy;
public GroupChatViewHolder(#NonNull View itemView) {
super(itemView);
txtGroupName = itemView.findViewById(R.id.group_name_display);
txtGroupCreatedBy = itemView.findViewById(R.id.group_createdby_display);
}
}
}
I would like to know how can I do a recyclerView that shows data that I got from this database reference:
Salas= new ArrayList<String>();
DatabaseReference referenceSalas = FirebaseDatabase.getInstance().getReference("salas/");
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("usuarios/");
FirebaseAuth autenticacao = FirebaseAuth.getInstance();
String emailUsu = autenticacao.getCurrentUser().getEmail();
reference.orderByChild("email").equalTo(emailUsu).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot datas : dataSnapshot.getChildren()) {
nomeProf = datas.child("nome").getValue().toString();
referenceSalas.orderByChild("nomeProf").equalTo(nomeProf).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot datas : dataSnapshot.getChildren()) {
Salas.add(datas.getKey());
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
I tried to do the RecyclerView like this:
public class salasFragment extends Fragment {
private RecyclerView mRecycleViewSalas;
private adapterSalas adapterSalas;
private ArrayList<salas> listaSalas= new ArrayList<>();
private LinearLayoutManager linearLayoutManager;
private TextView txtSalas, txtTeste;
private String nomeProf;
private String teste="", piru;
private DatabaseReference reference = FirebaseDatabase.getInstance().getReference("usuarios/");
private DatabaseReference referenceSalas = FirebaseDatabase.getInstance().getReference("salas/");
private ValueEventListener valueEventListenerSalas;
ArrayList<String> salasAula = new ArrayList<String>();
public salasFragment() {
// 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_salas, container, false);
final Context context = view.getContext();
txtSalas= view.findViewById(R.id.txtSalas);
txtTeste= view.findViewById(R.id.txtTeste);
mRecycleViewSalas= view.findViewById(R.id.recyclerSalas);
adapterSalas= new adapterSalas(listaSalas, context);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(context);
mRecycleViewSalas.setLayoutManager(layoutManager);
mRecycleViewSalas.setHasFixedSize(true);
mRecycleViewSalas.setAdapter(adapterSalas);
return view; }
#Override
public void onStart() {
super.onStart();
recuperarSalas();
}
#Override
public void onStop() {
super.onStop();
reference.removeEventListener(valueEventListenerSalas);
}
public void recuperarSalas(){
FirebaseAuth autenticacao = FirebaseAuth.getInstance();
String emailUsu = autenticacao.getCurrentUser().getEmail();
valueEventListenerSalas = reference.orderByChild("email").equalTo(emailUsu).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot datas : dataSnapshot.getChildren()) {
nomeProf = datas.child("nome").getValue().toString();
referenceSalas.orderByChild("nomeProf").equalTo(nomeProf).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot datas : dataSnapshot.getChildren()) {
salas salas=datas.getKey(salas.class);
listaSalas.add(salas);
}
adapterSalas.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
}
}
my adapter:
public class adapterSalas extends RecyclerView.Adapter<adapterSalas.myViewHolder> {
private List<salas> Salas;
private Context context;
public adapterSalas(List<salas> listaSalas, Context c ) {
this.Salas= listaSalas;
this.context = c;
}
#NonNull
#Override
public myViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
View itemLista = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_salas, parent, false);
return new myViewHolder(itemLista);
}
#Override
public void onBindViewHolder(#NonNull myViewHolder holder, int position) {
salas sala = Salas.get(position);
holder.btn1.setText(sala.getPrimeiro());
}
#Override
public int getItemCount() {
return Salas.size();
}
public class myViewHolder extends RecyclerView.ViewHolder{
Button btn1;
public myViewHolder(#NonNull View itemView) {
super(itemView);
btn1 = itemView.findViewById(R.id.btn1);
}
}
}
Although this line "salas salas=datas.getKey(salas.class);" does not work properly when I use "getKey", It only works when "getValue" is used. There is no way of me doing this project with "getValue" instead of "getKey". So there is any way that can make this recyclerView works properly with "getKey" ?
Have you got the data from the firebase already?
If you got the data in an arraylist already, simply plug it in an adapter (you will need to create a RecyclerView adapter, a class to describe the value of each RecyclerView items) and set it to the RecyclerView and you are good to go!
You can use FirebasRecyclerAdapter as you recyclerView adapter. check out this link for a guide on how to use it.
https://medium.com/android-grid/how-to-use-firebaserecycleradpater-with-latest-firebase-dependencies-in-android-aff7a33adb8b
The display from the Firebase database works fine, but when I try to delete an item from the database, the application crashes, although the deletion occurs. Writes on a null object reference in the string:
String postDescription = dataSnapshot.child("desc").getValue().toString();
Here is my code:
public class PostFragment extends Fragment {
private RecyclerView recyclerPost;
private DatabaseReference postReference;
private View view;
private LinearLayoutManager layoutManager;
public PostFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_post, container, false);
recyclerPost = view.findViewById(R.id.recycler_post);
postReference = FirebaseDatabase.getInstance().getReference().child("Posts");
postReference.keepSynced(true);
layoutManager = new LinearLayoutManager(getContext());
layoutManager.setReverseLayout(true);
layoutManager.setStackFromEnd(true);
recyclerPost.setHasFixedSize(true);
recyclerPost.setLayoutManager(layoutManager);
return view;
}
#Override
public void onStart() {
super.onStart();
Query query = postReference.orderByChild("timestamp");
FirebaseRecyclerOptions<Posts> options =
new FirebaseRecyclerOptions.Builder<Posts>()
.setQuery(query, Posts.class)
.build();
FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter<Posts, PostViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull final PostViewHolder holder, int position, #NonNull final Posts model) {
final String postId = getRef(position).getKey();
postReference.child(postId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String postDescription = dataSnapshot.child("desc").getValue().toString();
holder.postDesc.setText(postDescription);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
holder.delBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
postReference.child(postId).removeValue();
}
});
}
#NonNull
#Override
public PostViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int position) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.blog_item, viewGroup, false);
return new PostViewHolder(view);
}
};
adapter.startListening();
recyclerPost.setAdapter(adapter);
}
public class PostViewHolder extends RecyclerView.ViewHolder {
private TextView postDesc;
private Button delBtn;
private View view;
public PostViewHolder(#NonNull View itemView) {
super(itemView);
view = itemView;
postDesc = (TextView) view.findViewById(R.id.post_description);
delBtn = (Button) view.findViewById(R.id.del_post_btn);
}
}
}
Please tell me the solution to this problem.
You can try the following:
postReference.child(postId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
String postDescription = dataSnapshot.child("desc").getValue().toString();
holder.postDesc.setText(postDescription);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
You can use the method exists():
public boolean exists ()
Returns true if the snapshot contains a non-null value.
It will check if the datasnapshot is in the
database, if it is not in the database then you can add a snackbar or a toast.
More information here:
https://firebase.google.com/docs/reference/android/com/google/firebase/database/DataSnapshot#exists()
Every time a post is added to the adapter/list view, you now create a listener with addValueEventListener in your onBindViewHolder. This listener gets the value from the database, and then keeps listening for changes until you remove it. Since you never remove these listeners, over time they add up and things likely get out of sync.
The simplest solution is to use addListenerForSingleValueEvent:
#Override
protected void onBindViewHolder(#NonNull final PostViewHolder holder, int position, #NonNull final Posts model) {
final String postId = getRef(position).getKey();
postReference.child(postId).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String postDescription = dataSnapshot.child("desc").getValue().toString();
holder.postDesc.setText(postDescription);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
When you use addListenerForSingleValueEvent, the listener is removed right after onDataChange fires for the first time.
I'm trying to filter my user from a list of users in the recycler view. But I need to get the uid for each user inside the onBindViewHolder and I don't know how. I'd also like to move the code in onBindViewHolder to the bind method of the ViewHolder but I don't know how to get the context.
Here is what I've done
private void setRecyclerView() {
mUsersRecyclerView.setHasFixedSize(true);
mUsersRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new UserAdapter();
mUsersRecyclerView.setAdapter(mAdapter);
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Iterable<DataSnapshot> list = dataSnapshot.getChildren();
// Filter current user
//List<User> userList = new ArrayList<>();
for (DataSnapshot user : list) {
if (!user.getKey().equals(mCurrentUid)) {
mUserList.add(user.getValue(User.class));
}
}
// Setting data
// mAdapter.setItems(userList);
}
#Override public void onCancelled(#NonNull DatabaseError databaseError) {}
});
}
private class UserAdapter extends RecyclerView.Adapter<UserViewHolder> {
#NonNull
#Override
public UserViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new UserViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.user_item_layout, parent, false));
}
#Override
public void onBindViewHolder(#NonNull UserViewHolder holder, int position) {
User user = mUserList.get(position);
holder.bind(user);
// TODO: move this to holder.bind() method
holder.setThumb_image(user.getThumb_image(),getApplicationContext());
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent9 = new Intent(UsersActivity.this,ProfileActivity.class);
intent9.putExtra("user_id", uid); // TODO: get uid for each user here
startActivity(intent9);
}
});
}
#Override
public int getItemCount() {
return mUserList.size();
}
}
private class UserViewHolder extends RecyclerView.ViewHolder {
View mView;
public UserViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void bind(User user) {
TextView nameView = mView.findViewById(R.id.item_name);
nameView.setText(user.getName());
TextView statusView = mView.findViewById(R.id.item_status);
statusView.setText(user.getStatus());
}
public void setThumb_image(String thumb_image, Context ctx) {
CircleImageView imageView = mView.findViewById(R.id.item_image);
Picasso.with(ctx).load(thumb_image).placeholder(R.mipmap.icon).into(imageView);
}
}
Here is a working code with FirebaseRecyclerAdapter that doesn't filter the user.
Add firbaseId in your model while you store data to firebase database
Here's example user model class which stores user's information to firebase
public class User {
private String name;
private String address;
private String firebaseId;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getFirebaseId() {
return firebaseId;
}
public void setFirebaseId(String firebaseId) {
this.firebaseId = firebaseId;
}
}
And then store value like below
FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference databaseReference = firebaseDatabase.getReference(DATABASE_NAME);
String fireBaseId = databaseReference.push().getKey();
if (fireBaseId != null) {
User user = new User();
user.setName("SSB");
user.setAddress("Some address");
user.setFirebaseId(fireBaseId);
databaseReference.child(fireBaseId).setValue(user);
}
Then you can get id from user model class