Getting values from multiple Firebase database references in one cardView - android

I am developing an app which requires me to get reference from two Firebase database references in one cardview. Below is the model of the cardview
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginRight="35dp"
android:layout_marginLeft="35dp"
android:layout_marginBottom="60dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="75dp"
>
<ImageView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:layout_marginLeft="5dp"
app:srcCompat="#drawable/action_setup"
android:id="#+id/dPicture"/>
<TextView
android:text="Username"
android:layout_width="0dp"
android:layout_weight="4"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:id="#+id/posted_username"
android:paddingLeft="15dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:elevation="10dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/posted_image"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:src="#color/Orange"
/>
<TextView
android:text="Post Title..."
android:padding="15dp"
android:textSize="16dp"
android:textStyle="bold"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/posted_title"/>
<TextView
android:text="Summary..."
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingBottom="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLength="300"
android:maxLines="5"
android:id="#+id/posted_sharing"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
and this is how the database look like in Firebase
{
"Users" : {
"1" : {
"image" : "http://something.com/something",
"name" : "person 1"
},
"2" : {
"image" : "http://someone.com/someone",
"name" : "person 2"
}
},
"posts" : {
"post 1" : {
"content" : "test content 1",
"dPicture" : "http://something.com/something",
"picture" : "http://postimage.com/postimage",
"title" : "test title 1",
"uid" : 1,
"username" : "person 1"
},
"post 2" : {
"content" : "test content 2",
"dPicture" : "http://someone.com/someone",
"picture" : "http://postimage2.com/postimage2",
"title" : "test title 2",
"uid" : 2,
"username" : "person 2"
}
}
}
And the Activity code is
public class MainActivity extends AppCompatActivity {
private RecyclerView mPostedList;
private LinearLayoutManager mLayoutManager;
private DatabaseReference mDatabaseSharings;
private FirebaseAuth mAuth;
private FirebaseUser mCurrentUser;
private FirebaseAuth.AuthStateListener mAuthListener;
private DatabaseReference mDatabaseUsers;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAuth = FirebaseAuth.getInstance();
mDatabaseSharings = FirebaseDatabase.getInstance().getReference().child("posts");
mDatabaseUsers = FirebaseDatabase.getInstance().getReference().child("Users");
mCurrentUser = mAuth.getCurrentUser();
mDatabaseSharings.keepSynced(true);
final String uid = mCurrentUser.getUid();
//bring user to login activity when auth-state is null
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() == null) {
Intent loginIntent = new Intent(MainActivity.this, LoginActivity.class);
loginIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(loginIntent);
}
}
};
//keep users logged in
mDatabaseUsers.keepSynced(true);
mPostedList = (RecyclerView) findViewById(R.id.posted_list);
mPostedList.setHasFixedSize(true);
mPostedList.setLayoutManager(new LinearLayoutManager(this));
}
#Override
protected void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
//your adapter
FirebaseRecyclerAdapter<PostedModel, PostedModelViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<PostedModel, PostedModelViewHolder>(
PostedModel.class, R.layout.posted_row, PostedModelViewHolder.class, mDatabaseSharings
) {
#Override
protected void populateViewHolder(PostedModelViewHolder viewHolder, PostedModel model, int position) {
viewHolder.setTitle(model.getTitle());
viewHolder.setDPicture(getApplicationContext(), model.getDPicture());
viewHolder.setSummary(model.getSummary());
viewHolder.setImage(getApplicationContext(), model.getImage());
viewHolder.setUsername(model.getUsername());
final String post_key = getRef(position).getKey();
viewHolder.mView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
Intent delete_intent = new Intent(MainActivity.this, DeleteActivity.class);
delete_intent.putExtra("blog_id", post_key);
startActivity(delete_intent);
return false;
}
});
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent comment_intent = new Intent (MainActivity.this, CommentActivity.class);
comment_intent.putExtra("blog_id", post_key);
startActivity(comment_intent);
}
});
}
};
mPostedList.setAdapter(firebaseRecyclerAdapter);
mLayoutManager = new LinearLayoutManager(MainActivity.this);
mLayoutManager.setReverseLayout(true);
mLayoutManager.setStackFromEnd(true);
mPostedList.setLayoutManager(mLayoutManager);
}
public static class PostedModelViewHolder extends RecyclerView.ViewHolder{
View mView;
public PostedModelViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setTitle(String title){
TextView post_title = (TextView)mView.findViewById(R.id.posted_title);
post_title.setText(title);
}
public void setDPicture(Context ctx, String dPicture){
ImageView post_dPicture = (ImageView) mView.findViewById(R.id.dPicture);
Picasso.with(ctx).load(dPicture).into(post_dPicture);
}
public void setSummary (String summary){
TextView post_summary = (TextView)mView.findViewById(R.id.posted_sharing);
post_summary.setText(summary);
}
public void setImage(Context ctx, String image){
ImageView post_image = (ImageView) mView.findViewById(R.id.posted_image);
Picasso.with(ctx).load(image).into(post_image);
}
public void setUsername (String username){
TextView post_username = (TextView)mView.findViewById(R.id.posted_username);
post_username.setText(username);
}
}
}
Of course there is the PostedModel.class which is the getters and setters class for it
public class PostedModel {
private String title;
private String summary;
private String image;
private String dPicture;
private String username;
public PostedModel(){}
public PostedModel(String title, String summary, String image) {
this.title = title;
this.summary = summary;
this.image = image;
this.dPicture = dPicture;
this.username = username;
}
public String getDPicture() {
return dPicture;
}
public void setDPicture(String dPicture) {this.dPicture = dPicture;}
public String getTitle() {
return title;
}
public void setTitle(String title) {this.title = title;}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
Now as you can see I have a posting activity that pass both the username as well as the image value from the "Users" database to the "posts" database child (dPicture). However, when a user update his/her username, only the values from the "Users" database are changed and not from existing "posts"
I figure the most efficient way to do this is to populate the viewholder with data from the two database references, connecting both using the user's unique id which is the key in the "Users" database and as child (uid) in the "posts" database but I don't know how to do it... I am attaching a snapshot of the database screenshot with boxes to illustrate in case I am confusing people with my subpar technical language
So the goal is to get the red boxed data and paired it with green boxed data.
Many thanks for all helps beforehand!
Edit:
I don't know if I am on the right track with this... So after researching I think the right way to do it is using a valueEventListener for the Database that I want to get data from inside the adapter class...
So far I got this
FirebaseRecyclerAdapter<PostedModel, PostedModelViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<PostedModel, PostedModelViewHolder>(
PostedModel.class, R.layout.posted_row, PostedModelViewHolder.class, mDatabaseSharings
) {
//calling the value from the Summary.java class
#Override
protected void populateViewHolder(final PostedModelViewHolder viewHolder, final PostedModel model, final int position) {
mDatabaseUsers.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.getKey().toString() == mDatabaseSharings.child("uid").toString()){
viewHolder.setUsername(model.getUsername());
viewHolder.setDPicture(getApplicationContext(), model.getDPicture());
}
viewHolder.setTitle(model.getTitle());
viewHolder.setSummary(model.getSummary());
viewHolder.setImage(getApplicationContext(), model.getImage());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
But I am getting the key instead of the value passed haha

Try creating two array list say ArrayList abc,def. Then after you fetch the data from Users node, write assign username and image like abc.username. Right after this, fetch data from Posts node and do the same thing for the rest of the data. Then at the end of both the functions,write def.add(abc); I think this should do the job.

Related

my application that it crashes when I try to use the adapter

my code
**I have a UserAdapter, and a Search Fragment and the user_item and user class. The problem is, the three Click Listeners to open the "Search Fragment " the app crashe!! and close.
i hope so i give u good explanation for the problem
and thanks for the help in advance
**
public class SearchFragment extends Fragment {
private RecyclerView recyclerView;
private UserAdapter userAdapter;
private List<User> userList;
EditText search_bar;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_search, container, false);
recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
search_bar = view.findViewById(R.id.search_bar);
userList = new ArrayList<>();
userAdapter = new UserAdapter(getContext(), userList, true);
recyclerView.setAdapter(userAdapter);
readUsers();
search_bar.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
searchUsers(charSequence.toString().toLowerCase());
}
#Override
public void afterTextChanged(Editable editable) {
}
});
return view;
}
private void searchUsers(String s){
Query query = FirebaseDatabase.getInstance().getReference("Users").orderByChild("username")
.startAt(s)
.endAt(s+"\uf8ff");
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
userList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
User user = snapshot.getValue(User.class);
userList.add(user);
}
userAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void readUsers() {
final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (search_bar.getText().toString().equals("")) {
userList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
User user = snapshot.getValue(User.class);
userList.add(user);
}
userAdapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
** my code class Use**
public class User {
private String id;
private String username;
private String fullname;
private String imageurl;
private String bio;
public User(String id, String username, String fullname, String imageurl, String bio) {
this.id = id;
this.username = username;
this.fullname = fullname;
this.imageurl = imageurl;
this.bio = bio;
}
public User() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getImageurl() {
return imageurl;
}
public void setImageurl(String imageurl) {
this.imageurl = imageurl;
}
public String getBio() {
return bio;
}
public void setBio(String bio) {
this.bio = bio;
}
}
my code UserAdapter
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ImageViewHolder> {
private Context mContext;
private List<User> mUsers;
private boolean isFragment;
private FirebaseUser firebaseUser;
public UserAdapter(Context context, List<User> users, boolean isFragment){
mContext = context;
mUsers = users;
this.isFragment = isFragment;
}
#NonNull
#Override
public UserAdapter.ImageViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.user_item, parent, false);
return new UserAdapter.ImageViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final UserAdapter.ImageViewHolder holder, final int position) {
firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
final User user = mUsers.get(position);
holder.btn_follow.setVisibility(View.VISIBLE);
isFollowing(user.getId(), holder.btn_follow);
holder.username.setText(user.getUsername());
holder.fullname.setText(user.getFullname());
Glide.with(mContext).load(user.getImageurl()).into(holder.image_profile);
if (user.getId().equals(firebaseUser.getUid())){
holder.btn_follow.setVisibility(View.GONE);
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (isFragment) {
SharedPreferences.Editor editor = mContext.getSharedPreferences("PREFS", MODE_PRIVATE).edit();
editor.putString("profileid", user.getId());
editor.apply();
((FragmentActivity) mContext).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new ProfileFragment()).commit();
} else {
Intent intent = new Intent(mContext, Main2Activity.class);
intent.putExtra("publisherid", user.getId());
mContext.startActivity(intent);
}
}
});
holder.btn_follow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (holder.btn_follow.getText().toString().equals("follow")) {
FirebaseDatabase.getInstance().getReference().child("Follow").child(firebaseUser.getUid())
.child("following").child(user.getId()).setValue(true);
FirebaseDatabase.getInstance().getReference().child("Follow").child(user.getId())
.child("followers").child(firebaseUser.getUid()).setValue(true);
addNotification(user.getId());
} else {
FirebaseDatabase.getInstance().getReference().child("Follow").child(firebaseUser.getUid())
.child("following").child(user.getId()).removeValue();
FirebaseDatabase.getInstance().getReference().child("Follow").child(user.getId())
.child("followers").child(firebaseUser.getUid()).removeValue();
}
}
});
}
private void addNotification(String userid){
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Notifications").child(userid);
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("userid", firebaseUser.getUid());
hashMap.put("text", "started following you");
hashMap.put("postid", "");
hashMap.put("ispost", false);
reference.push().setValue(hashMap);
}
#Override
public int getItemCount() {
return mUsers.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder {
public TextView username;
public TextView fullname;
public CircleImageView image_profile;
public Button btn_follow;
public ImageViewHolder(View itemView) {
super(itemView);
username = itemView.findViewById(R.id.username);
fullname = itemView.findViewById(R.id.fullname);
image_profile = itemView.findViewById(R.id.image_profile);
btn_follow = itemView.findViewById(R.id.btn_follow);
}
}
private void isFollowing(final String userid, final Button button){
final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference()
.child("Follow").child(firebaseUser.getUid()).child("following");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.child(userid).exists()){
button.setText("following");
} else{
button.setText("follow");
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
** user_item**
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:orientation="vertical">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="#+id/image_profile"
android:src="#mipmap/ic_launcher"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#+id/image_profile"
android:layout_marginStart="5dp"
android:orientation="vertical"
android:layout_centerVertical="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/username"
android:text="username"
android:maxLines="1"
android:textStyle="bold"
android:textColor="#color/colorPrimaryDark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/fullname"
android:text="full_name"
android:maxLines="1"/>
</LinearLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="30dp"
android:background="#drawable/button_background"
android:id="#+id/btn_follow"
android:textColor="#color/colorPrimary"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:visibility="gone"/>
</RelativeLayout>
stack trace
E/AndroidRuntime: FATAL EXCEPTION: main
Process: commenting, PID: 24881
java.lang.ClassCastException: androidx.appcompat.widget.AppCompatButton cannot be cast to androidx.recyclerview.widget.RecyclerView
at commenting.Fragment.SearchFragment.onCreateView(SearchFragment.java:47)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
at android.os.Handler.handleCallback(Handler.java:907)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
I/Process: Sending signal. PID: 24881 SIG: 9
Fragment.SearchFragment
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment.SearchFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/bar"
android:background="?android:attr/windowBackground">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
android:id="#+id/toolbar">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_search_light"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/search_bar"
android:background="#android:color/transparent"
android:hint="search_bar"
android:layout_marginStart="10dp"
android:inputType="text"/>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/bar"
android:id="#+id/recycler_view"/>
</RelativeLayout>
It looks like your search fragment layout doesn't have the RecyclerView component and the button on that layout has the recycler_view id which you try to use to inflate your RecyclerView. That's why you're getting this exception.
Add a RecyclerView to your layout and set its id to recycler_view so that you can grab the RV in your code.

Is it possible to Fetch the Data from this "Users" Object to this layout?

I am making this Simple Chat Application, where any person can register with his Name, Email and Pass , then Login and start chatting.
Messages are sent and received successfully from DB, now i am having the problem is "How can i get the Usernames of the Respective persons in the Chat Layout".
Also while registering process, i saved the username and Email to Database inside "Users" node.
This is what i have tried So Far :
This is my Database Screenshot :
This is how the app look so far :
App Screenshot
Here is my SignUp Activity :
private void DOSignup() {
final String get_name = name.getText().toString().trim();
final String get_email = email.getText().toString().trim();
String get_password = password.getText().toString().trim();
mAuth.createUserWithEmailAndPassword(get_email,get_password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
FirebaseUser firebaseUser = mAuth.getCurrentUser();
Log.e("Current User", firebaseUser.toString());
// String name = firebaseUser.getDisplayName();
// Log.e("Name is :", name);
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference().child("Users");
GetUserName getUserName = new GetUserName(get_name,get_email);
String id = databaseReference.push().getKey();
databaseReference.child(id).setValue(getUserName);
Toast.makeText(getApplicationContext(), "Registration successful!", Toast.LENGTH_LONG).show();
// progressBar.setVisibility(View.GONE);
Intent intent = new Intent(SignUpActivity.this, LoginActivity.class);
startActivity(intent);
}
else {
Toast.makeText(getApplicationContext(), "Registration failed! Please try again later", Toast.LENGTH_LONG).show();
// progressBar.setVisibility(View.GONE);
}
}
});
Model Class to save UserName and Email to DB :
public class GetUserName {
String username;
String email;
public GetUserName() {
}
public GetUserName(String username, String email) {
this.username = username;
this.email = email;
}
public String getUsername() {
return username;
}
public String getEmail() {
return email;
}
}
This is my Model Class to show Messages :
public class ChatModel {
String messages;
public ChatModel() {
}
public ChatModel(String messages) {
this.messages = messages;
}
public String getMessages() {
return messages;
}
}
This is my chat_layout.xml :
<TextView
android:id="#+id/userName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="Lacie"
android:textSize="18sp" />
<TextView
android:id="#+id/dateTime"
android:layout_margin="6dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:text="07-10-2016 (21:50:21)" />
</RelativeLayout>
<TextView
android:id="#+id/message_body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/l1"
android:background="#drawable/my_message"
android:elevation="2dp"
android:padding="10dp"
android:text="Placeholder message"
android:textColor="#fff"
android:textSize="13sp" />
This is my ChatAdapter :
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_layout,
parent, false);
return new ViewHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull ViewHolder holder, int position, #NonNull ChatModel model) {
ChatModel model1 = chatModelList.get(position);
GetUserName getUserName = new GetUserName();
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
holder.messages.setText(model1.getMessages());
holder.userName.setText(databaseReference.getKey());
// holder.userName.setText(getUserName.getUsername());
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView messages,userName;
public ViewHolder(#NonNull View itemView) {
super(itemView);
messages = itemView.findViewById(R.id.message_body);
userName = itemView.findViewById(R.id.userName);
Please Give your Ideas to how can i get the Respective Usernames insted of "Lacie" in chat_layout. Thanks

Firestore data doesn't show up in RecyclerView

I'm trying to put my firestore data within a recyclerview in Android. The app comes up with no errors, however no data shows up.
public class Diseaselist extends AppCompatActivity {
private TextView textView;
private FirebaseFirestore mDatabaseRef;
private Query mChartsQuery;
private RecyclerView mRecycler;
private FirebaseAuth mAuth;
private FirestoreRecyclerAdapter<Upload, ProductViewHolder> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_diseaselist);
RecyclerView recyclerView = findViewById(R.id.goodmeme);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
mAuth = FirebaseAuth.getInstance();
FirebaseUser currentUser = mAuth.getCurrentUser();
String useruid = currentUser.getUid();
Query query = rootRef.collection("users").document(useruid).collection("diagnoses")
.orderBy("disease", Query.Direction.ASCENDING);
FirestoreRecyclerOptions<Upload> options = new FirestoreRecyclerOptions.Builder<Upload>()
.setQuery(query, Upload.class)
.build();
adapter = new FirestoreRecyclerAdapter<Upload, ProductViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull ProductViewHolder holder, int position, #NonNull Upload productModel) {
holder.setProductName(productModel.getDisease());
}
#NonNull
#Override
public ProductViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
android.view.View views = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_diseaselist, parent, false);
return new ProductViewHolder(views);
}
};
recyclerView.setAdapter(adapter);
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
if (adapter != null) {
adapter.stopListening();
}
}
private class ProductViewHolder extends RecyclerView.ViewHolder {
private android.view.View view;
ProductViewHolder(android.view.View itemView) {
super(itemView);
view = itemView;
}
void setProductName(final String productName) {
CardView cview =view.findViewById(R.id.cardview);
textView = view.findViewById(R.id.texty);
textView.setText(productName);
cview.setOnClickListener(new android.view.View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
Toast.makeText(getApplicationContext(), productName, Toast.LENGTH_SHORT).show();
}
});
}
}
Layout File:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".Diseaselist"
tools:orientation="vertical">
<TextView
android:id="#+id/texty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="30sp"/>
<android.support.v7.widget.CardView
android:id="#+id/cardview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<ImageView
android:id="#+id/person_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginRight="16dp" />
<TextView
android:id="#+id/person_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/person_photo"
android:textSize="30sp" />
<TextView
android:id="#+id/person_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/person_name"
android:layout_toRightOf="#+id/person_photo" />
</RelativeLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/goodmeme"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Firestore structure Firestore Structure Screenshot 2
Upload Class code:
package com.Provendor.Provendor;
import android.os.Parcel;
import android.os.Parcelable;
import java.io.Serializable;
import java.util.Calendar;
public class Upload implements Parcelable {
private String mName;
private String mImageUrl;
private String mdisease;
private String mdate;
private float mconfidence;
#Override
public int describeContents() {
return 0;
}
// write your object's data to the passed-in Parcel
#Override
public void writeToParcel(Parcel out, int flags) {
out.writeFloat(mconfidence);
out.writeString(mName);
out.writeString(mImageUrl);
out.writeString(mdisease);
out.writeString(mdate);
}
// this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
public static final Parcelable.Creator<Upload> CREATOR = new Parcelable.Creator<Upload>() {
public Upload createFromParcel(Parcel in) {
return new Upload(in);
}
public Upload[] newArray(int size) {
return new Upload[size];
}
};
// example constructor that takes a Parcel and gives you an object populated with it's values
private Upload(Parcel in) {
mconfidence = in.readInt();
mName = in.readString();
mImageUrl = in.readString();
mdisease = in.readString();
mdate = in.readString();
}
public Upload() {
mName= ""; //empty constructor needed
}
public Upload(String name, String imageUrl, String disease, float confidence) {
if (name.trim().equals("")) {
name = "No Name";
}
mdisease=disease;
mdate=java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime());
mName = name;
mImageUrl = imageUrl;
mconfidence=confidence;
}
public String getName() {
return mName;
}
public String getDisease() {
return mdisease;
}
public float getConfidence() {
return mconfidence;
}
public String getDate() {
return mdate;
}
public void setName(String name) {
mName = name;
}
public void setdate() {
mdate=java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime());
}
public void setDisease(String disease) {
mdisease = disease;
}
public void setConfidence(float confidence) {
mconfidence = confidence;
}
public String getImageUrl() {
return mImageUrl;
}
public void setImageUrl(String imageUrl) {
mImageUrl = imageUrl;
}
}
I expect the output to produce a list of diseases based on the firestore collection, however the recyclerview is left empty. When attached to debug, no errors come up! Thanks for looking this over!
You aren't getting anything from the database because the name of your fields inside the Upload class are different than the name of the fields that exist in the database. Both should match. To solve this, you either change all the name of your fields inside your Upload class to match the properties that exist in the database or your can use annotations. Because I see that you are using private fields and public getters, you should use the PropertyName annotation only in front of the getter, for instance your getName() getter should look like this:
#PropertyName("name")
public String getName() {
return mName;
}

How to retrieve child values from firebase database and display them in a list of layouts?

I have a Fragment class where i want to display a list of layouts where the layout is updated with firebase data values.
This is how my data base looks (user_dubs > user_id > photo id):
Here's the fragment (UPDATED):
public class DubsFragment extends Fragment {
private static final String TAG = "DubsFragment";
//firebase
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference myRef;
//widgets
private EditText mthisdub;
private ListView mListView;
//vars
private ArrayList<String> mDubs;
private ArrayAdapter<String> adapter;
private Context mContext;
private PostDubs mpostdubs;
private String userID;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_mydubs, container, false);
mListView = (ListView) view.findViewById(R.id.listViewz);
mDubs = new ArrayList<>();
mContext = getActivity();
mpostdubs = new PostDubs();
adapter = new ArrayAdapter<String>(mContext, R.layout.layout_dubs_listitem, R.id.getusername, mDubs);
mListView.setAdapter(adapter);
setupFirebaseAuth();
return view;
}
private void setupFirebaseAuth(){
Log.d(TAG, "setupFirebaseAuth: setting up firebase auth.");
mAuth = FirebaseAuth.getInstance();
mFirebaseDatabase = FirebaseDatabase.getInstance();
myRef = mFirebaseDatabase.getReference();
userID = mAuth.getCurrentUser().getUid();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference
.child(getString(R.string.dbname_userdubs))
.child(userID)
.orderByChild(getString(R.string.field_photoid));
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for ( DataSnapshot singleSnapshot : dataSnapshot.getChildren()) {
mpostdubs = singleSnapshot.getValue(PostDubs.class);
mDubs.add(mpostdubs.getEditdub().toString());
adapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
#Override
public void onStop() {
super.onStop();
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);
}
}
}
Post Dubs Class:
public class PostDubs {
private String editdub;
private String dubdate;
private String user_id;
private String photoid;
private String username;
private Context mContext;
public PostDubs(String user_id, String editdub, String photoid, String dubdate, String username){
this.user_id = user_id;
this.editdub = editdub;
this.dubdate = dubdate;
this.photoid = photoid;
this.username = username;
}
public PostDubs() {
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public String getEditdub() {
return editdub;
}
public void setEditdub(String editdub) {
this.editdub = editdub;
}
public String getDubdate() {
return dubdate;
}
public void setDubdate(String dubdate) {
this.dubdate = dubdate;
}
public String getPhotoid() {
return photoid;
}
public void setPhotoid(String photoid) {
this.dubdate = photoid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
#Override
public String toString() {
return "User{" +
"user_id='" + editdub + '\'' +
", phone_number='" + dubdate + '\'' +
'}';
}
}
Here's the layout_dubs_listitem.xml:
<?xml version="1.0" encoding="utf-8" ?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto">
<RelativeLayout android:layout_width="match_parent"
android:layout_height="100dp">
<de.hdodenhof.circleimageview.CircleImageView android:layout_width="75dp"
android:layout_height="75dp"
app:civ_border_color="#color/black"
app:civ_border_width="0.5dp"
android:id="#+id/profile_image"
android:layout_marginLeft="20dp"
android:layout_centerVertical="true" />
<RelativeLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/profile_image"
android:layout_centerVertical="true">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:textSize="22sp"
android:textColor="#color/black"
android:id="#+id/editdub"
android:text=""/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:textSize="15sp"
android:layout_centerVertical="true"
android:textColor="#color/black"
android:id="#+id/getusername"
android:text=""/>
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
For the test, I'm just trying to get the edit dub in the layout but it is not working at all. I am sure I am doing something stupid.
Please guide me with this problem and it would be very helpful if you could help me update the layout with other child values like username. Thanks.
I fixed it by ordering my child in the firebase correctly.

Data in recycler view not being uploaded to Firebase

So I did some research about this but was unable to solve this problem and every solution online led to me to a new error.
I am currently working on an Events App and relatively new to Android Studio.
I have a RecyclerView in an Admin app that verifies all the Event data uploaded on Firebase by an organizer. The organizer uploads the data such as event_tile, event_desc and event_image. This is stored in Firebase under root "Event". Later the Admin App receives these requests in the form of a recycler view, and has a button to approve them. All the approved events are would be stored in a separate table in Firebase with root "Approved_Events".
I am getting stuck in the approval part. The code is running fine with no errors but no data is being uploaded to my Firebase console.
Here is my Main Activity
public class MainActivity extends AppCompatActivity {
private RecyclerView request_eventList;
private DatabaseReference mRef, aRef;
private Button verify_button;
private TextView request_title, request_desc;
private ImageView request_image;
ProgressDialog progressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
progressDialog = new ProgressDialog(this);
mRef = FirebaseDatabase.getInstance().getReference().child("Event");
setContentView(R.layout.activity_main);
request_eventList = (RecyclerView) findViewById(R.id.request_eventList);
request_eventList.setHasFixedSize(true);
request_eventList.setLayoutManager(new LinearLayoutManager(this));
}
#Override
protected void onStart() {
super.onStart();
FirebaseRecyclerAdapter<Event, RequestViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Event, RequestViewHolder>(
Event.class,
R.layout.admin_event_row,
RequestViewHolder.class,
mRef
) {
#Override
protected void populateViewHolder(RequestViewHolder viewHolder, Event model, int position) {
viewHolder.setTitle(model.getTitle());
viewHolder.setDesc(model.getDesc());
viewHolder.setImage(getApplicationContext(), model.getImage());
}
};
request_eventList.setAdapter(firebaseRecyclerAdapter);
}
public static class RequestViewHolder extends RecyclerView.ViewHolder {
View mView;
public Button verify_button;
DatabaseReference mRef, aRef;
ProgressDialog progressDialog;
public RequestViewHolder(View itemView) {
super(itemView);
mView = itemView;
progressDialog = new ProgressDialog(mView.getContext());
verify_button = (Button) mView.findViewById(R.id.approve_button);
mRef = FirebaseDatabase.getInstance().getReference().child("Event");
aRef = FirebaseDatabase.getInstance().getReference().child("ApprovedEvents");
verify_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {mRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map <String, String> map = (Map<String, String>) dataSnapshot.getValue();
String title_val = map.get("title");
String desc_val = map.get("desc");
String image_val = map.get("image");
aRef.child("approved_title").setValue(title_val);
aRef.child("approved_desc").setValue(desc_val);
aRef.child("approved_image").setValue(image_val);
progressDialog.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
}
public void setTitle(String title) {
TextView request_title = (TextView) mView.findViewById(R.id.request_title);
request_title.setText(title);
}
public void setDesc(String desc) {
TextView request_desc = (TextView) mView.findViewById(R.id.request_desc);
request_desc.setText(desc);
}
public void setImage(Context ctx, String image) {
ImageView request_image = (ImageView) mView.findViewById(R.id.request_image);
Picasso.with(ctx).load(image).into(request_image);
}
}
}
MainActivity XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.admin.admin.MainActivity">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/request_eventList"
android:clickable="true">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
Event Java Class
public class Event {
private String title, desc, image;
public Event(String title, String desc, String image) {
this.title = title;
this.desc = desc;
this.image = image;
}
public Event(){
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
}
admin_event_row XML file that will fill the recyclerView
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/request_image"
android:src="#drawable/abc_btn_check_material"
android:adjustViewBounds="true" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/request_title"
android:text="Title will come here "
android:padding="10dp"
android:textStyle="bold"
android:textSize="15dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/request_desc"
android:text="Desc will come here "
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingBottom="10dp" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/approve_button"
android:text="Yeah it's Cool "/>
</LinearLayout>
Final App Look
If your Event has more unapproved child, move verify_button.setOnClickListener from Holder to Adapter-populateViewHolder. You have to connect verify_button.setOnClickListener to row in recycleviewer to get values of title, desc and image from clicked item.
protected void populateViewHolder(RequestViewHolder viewHolder, Event model, int position) {
viewHolder.setTitle(model.getTitle());
viewHolder.setDesc(model.getDesc());
viewHolder.setImage(getApplicationContext(), model.getImage());
final String title = model.getTitle();
final String desc = model.getDesc();
final String image = model.getImage();
final DatabaseReference aRef = FirebaseDatabase.getInstance().getReference();
viewHolder.verify_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
String key = aRef.child("ApprovedEvents").push().getKey();
Event event = new Event(title, desc, image );
Map<String, Object> eventValues = event.toMap();
Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put("/ApprovedEvents/" + key, eventValues);
aRef.updateChildren(childUpdates);
}
});
}
};

Categories

Resources