Couldnt display data from firebase in recyclerview - java

I am developing an android app which shows the user with the latest jobs from various fields. I want to display the jobs that the user has applied so far in "Your Applications" section.
But the values are not getting retrieved. It displays a blank activity. I have attached the code.
Applications.java
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.app.Application;
import android.app.ProgressDialog;
import android.os.Bundle;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class Applications extends AppCompatActivity {
DatabaseReference databaseReference;
FirebaseDatabase firebaseDatabase;
RecyclerView recyclerView;
FirebaseUser user;
FirebaseAuth mAuth;
ArrayList<Post> posts;
MyAdap adap;
ProgressDialog pd;
long maxid=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_applications);
recyclerView = findViewById(R.id.work);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mAuth = FirebaseAuth.getInstance();
user = mAuth.getCurrentUser();
posts = new ArrayList<>();
pd= new ProgressDialog(Applications.this);
pd.setMessage("Loading...");
pd.show();
getSupportActionBar().setTitle("Your Applications");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
firebaseDatabase = FirebaseDatabase.getInstance();
databaseReference = firebaseDatabase.getReference("Job Applications");
Query query = databaseReference.orderByChild(String.valueOf(maxid+1)).equalTo(user.getUid());
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()){
Post p = ds.getValue(Post.class);
posts.add(p);
}
pd.dismiss();
adap = new MyAdap(Applications.this, posts);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
pd.dismiss();
}
});
}
}
Posts.java
public class Post {
private String jobtitle, jobtype, company, location;
public Post() {
}
public Post(String jobtitle, String jobtype, String company, String location) {
this.jobtitle = jobtitle;
this.jobtype = jobtype;
this.company = company;
this.location = location;
}
public String getJobtitle() {
return jobtitle;
}
public void setJobtitle(String jobtitle) {
this.jobtitle = jobtitle;
}
public String getJobtype() {
return jobtype;
}
public void setJobtype(String jobtype) {
this.jobtype = jobtype;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
MyAdap.java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class MyAdap extends RecyclerView.Adapter<MyAdap.ViewHolder> {
Context cb;
ArrayList<Post> posts;
public MyAdap(Context c, ArrayList<Post> applications){
cb=c;
posts=applications;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(cb).inflate(R.layout.post, parent,false));
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.jobTitle.setText(posts.get(position).getJobtitle());
holder.jobType.setText(posts.get(position).getJobtype());
holder.location.setText(posts.get(position).getLocation());
holder.companyName.setText(posts.get(position).getCompany());
}
#Override
public int getItemCount() {
return posts.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView jobTitle, jobType,companyName,location;
public ViewHolder(#NonNull View itemView) {
super(itemView);
jobTitle = itemView.findViewById(R.id.jobTitle);
jobType = itemView.findViewById(R.id.jobType);
companyName = itemView.findViewById(R.id.companyName);
location = itemView.findViewById(R.id.location);
}
}
}
Here is the image of the database.

I think you have a problem with your orderByChild and equalTo method in the Query section. Please try without the Query and if you want to add sorting read details here.
And one more thing you don't have any jobtype in your database but in your POJO class you have this field in your Constructor.
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()){
Post p = ds.getValue(Post.class);
posts.add(p);
}
pd.dismiss();
adap = new MyAdap(Applications.this, posts);
recyclerView.setAdapter(adap);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
pd.dismiss();
}
});

You are not attaching adapter to recycle view
adap = new MyAdap(Applications.this, posts);
recyclerView.setAdapter(adap)
you need to set adpater to recycle view

As said by abdul add the adapter to the recycler view and also add the android lifecycle method onStart(); method and in the add adapter.startlisteneing();

Related

How to put in Firebase in the LIKE_ID, POST_ID + USER_ID

I got a big problem that I can't fix by myself, I need to put in Firebase the Likes of my social network app with the id POSTID + USERID, but actually, I don't know how to bring the postid and paste it in the likes id (post key).
The main problem is about the post_key: it gives me a random id instead of the post id but honestly, I have no idea how to bring it, so the result is LIKESID = RANDOMID + USERID, instead of LIKESID = POSTID + USERID
I think is very simple to fix it for an expert programmer but as a beginner, this blows my mind
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
ArrayList<Model> mList;
Context context;
public MyAdapter(Context context, ArrayList<Model> mList){
this.mList = mList;
this.context = context;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.item , parent , false);
return new MyViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
Model model = mList.get(position);
holder.nickname.setText(model.getNickname());
holder.date.setText(model.getDate());
holder.time.setText(model.getTime());
holder.post.setText(model.getPost());
}
#Override
public int getItemCount() {
return mList.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder{
ImageButton like;
Boolean likechecker = false;
String currentUserID;
FirebaseAuth mAuth;
TextView date, time, nickname, post, liketextview;
DatabaseReference LikesRef;
DatabaseReference Database = FirebaseDatabase.getInstance().getReference();
final String post_key = Database.push().getKey();
Integer countlikes;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
date = itemView.findViewById(R.id.date_text);
time = itemView.findViewById(R.id.time_text);
post = itemView.findViewById(R.id.post_text);
nickname = itemView.findViewById(R.id.nickname_text);
like = itemView.findViewById(R.id.like_btn);
mAuth = FirebaseAuth.getInstance();
currentUserID = mAuth.getCurrentUser().getUid();
LikesRef = (FirebaseDatabase.getInstance().getReference().child("Likes"));
setlikebuttonstatus(post_key);
like.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
likechecker = true;
LikesRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(likechecker.equals(true)){
if (snapshot.child(post_key).hasChild(currentUserID)){
LikesRef.child(post_key).child(currentUserID).removeValue();
likechecker = false;
}
else {
LikesRef.child(post_key).child(currentUserID).setValue(true);
likechecker = false;
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
});
}
public void setlikebuttonstatus(final String post_key) {
post = itemView.findViewById(R.id.post_text);
liketextview = itemView.findViewById(R.id.like_textview);
LikesRef = (FirebaseDatabase.getInstance().getReference().child("Likes"));
mAuth = FirebaseAuth.getInstance();
currentUserID = mAuth.getCurrentUser().getUid();
LikesRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.child(post_key).hasChild(currentUserID)){
countlikes = (int) snapshot.child(post_key).getChildrenCount();
like.setImageResource(R.drawable.like);
liketextview.setText(Integer.toString(countlikes) + " Likes");}
else {
countlikes = (int) snapshot.child(post_key).getChildrenCount();
like.setImageResource(R.drawable.notlike);
liketextview.setText(Integer.toString(countlikes) + " Likes");
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
}
Homepage.Activity
package com.example.scrapbase11;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerAdapter_LifecycleAdapter;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.google.firebase.storage.StorageReference;
import com.squareup.picasso.Picasso;
import java.awt.font.TextAttribute;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.EventListener;
import java.util.HashMap;
import java.util.List;
import de.hdodenhof.circleimageview.CircleImageView;
public class HomepageActivity extends AppCompatActivity {
String currentUserID;
private FirebaseAuth mAuth;
private DatabaseReference UsersRef, PostsRef, LikesRef;
private TextView nicknamedisplayed, displaynumblikes;
private EditText posttext;
private CircleImageView circleImageView;
private Button pubblicabtn;
private String saveCurrentdate, saveCurrenttime, tsaveCurrentdate, tsaveCurrenttime, postRandomName, nickname;
private RecyclerView recyclerView;
private FirebaseDatabase db = FirebaseDatabase.getInstance();
private DatabaseReference root = db.getReference().child("Posts");
private DatabaseReference Database = FirebaseDatabase.getInstance().getReference();
private MyAdapter adapter;
private ArrayList<Model> list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_homepage);
displaynumblikes = (TextView) findViewById(R.id.like_textview);
nicknamedisplayed = (TextView) findViewById(R.id.nickname_textview);
posttext = (EditText) findViewById(R.id.postedittext);
pubblicabtn = (Button) findViewById(R.id.pubblica_btn);
circleImageView = (CircleImageView) findViewById(R.id.home_profileimage);
mAuth = FirebaseAuth.getInstance();
currentUserID = mAuth.getCurrentUser().getUid();
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
list = new ArrayList<>();
adapter = new MyAdapter(this, list);
recyclerView.setAdapter(adapter);
Calendar calFordDate = Calendar.getInstance();
Calendar calFordTime = Calendar.getInstance();
SimpleDateFormat currentDate = new SimpleDateFormat("dd/MM/yyyy");
saveCurrentdate = currentDate.format(calFordDate.getTime());
SimpleDateFormat currentTime = new SimpleDateFormat("HH:mm");
saveCurrenttime = currentTime.format(calFordTime.getTime());
final String post_key = Database.push().getKey();
circleImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Sendtomyprofile();
}
});
nicknamedisplayed.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Sendtomyprofile();
}
});
root.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot dataSnapshot : snapshot.getChildren()){
Model model = dataSnapshot.getValue(Model.class);
list.add(model);
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
UsersRef = (FirebaseDatabase.getInstance().getReference().child("Users"));
PostsRef = (FirebaseDatabase.getInstance().getReference().child("Posts"));
LikesRef = (FirebaseDatabase.getInstance().getReference().child("Likes"));
pubblicabtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Savepostmethod();
}
});
// codice per far visualizzare il proprio nickname
UsersRef.child(currentUserID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
nickname = snapshot.child("nickname").getValue().toString();
nicknamedisplayed.setText("Welcome back " + nickname);
}
}
// fine del codice per visualizzare il proprio nickname
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(HomepageActivity.this, "Database error :)", Toast.LENGTH_SHORT).show();
}
});
}
private void Sendtomyprofile() {
Intent Gotomyprofileintent =new Intent(HomepageActivity.this, ProfileActivity.class);
startActivity(Gotomyprofileintent);
}
private void Savepostmethod() {
String post = posttext.getText().toString();
if (TextUtils.isEmpty(post)) {
Toast.makeText(this, "Please write something...", Toast.LENGTH_SHORT).show();
} else {
Calendar tcalFordDate = Calendar.getInstance();
Calendar tcalFordTime = Calendar.getInstance();
SimpleDateFormat tcurrentDate = new SimpleDateFormat("ddMMyyyy");
tsaveCurrentdate = tcurrentDate.format(tcalFordDate.getTime());
SimpleDateFormat tcurrentTime = new SimpleDateFormat("HHmm");
tsaveCurrenttime = tcurrentTime.format(tcalFordTime.getTime());
postRandomName = tsaveCurrentdate + tsaveCurrenttime;
HashMap postMap = new HashMap();
postMap.put("userid", currentUserID);
postMap.put("nickname", nickname);
postMap.put("post", post);
postMap.put("time", saveCurrenttime);
postMap.put("date", saveCurrentdate);
PostsRef.child(currentUserID + postRandomName).updateChildren(postMap).addOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(#NonNull Task task) {
if(task.isSuccessful()) {
Toast.makeText(HomepageActivity.this, "Pubblicazione riuscita", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(HomepageActivity.this, "Pubblicazione non riuscita, controlla la tua connessione internet", Toast.LENGTH_SHORT).show();
}
}
});
}
}}
The issue is obvious. You create here:
final String post_key = Database.push().getKey();
Always a random Uid. And by using it here:
setlikebuttonstatus(post_key);
You always end up with LIKESID = RANDOMID + USERID as explained in the question. You also wrote the solution: Write the postUid instead the random one.
What is the model here giving you back? Is it just a string?:
holder.post.setText(model.getPost());
Can you share with us how you get the list of posts and we can find a solution. We basicaly need only the key from each post snapshot instead of the data. You probably have it but it's not mapped for your other code to get it.
With the code from the edit you can get the post uid like this and maybe add to the Model class a property id and add it afterdwards like this:
Model model = dataSnapshot.getValue(Model.class);
String key=dataSnapshot.getKey();
model.id=key;
list.add(model);

Can't convert object of type java.util.ArrayList to type com.example.soas.POJO.Service

I am facing error While retrieving data from firebase Here is the error that i am receiving while getting data from firebase..
com.google.firebase.database.DatabaseException: Can't convert object of type java.util.ArrayList to type com.example.soas.POJO.Service
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(com.google.firebase:firebase-database##19.3.0:435)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-database##19.3.0:231)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(com.google.firebase:firebase-database##19.3.0:79)
at com.google.firebase.database.DataSnapshot.getValue(com.google.firebase:firebase-database##19.3.0:203)
at com.example.soas.Activities.Services$2.onDataChange(Services.java:80)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database##19.3.0:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database##19.3.0:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database##19.3.0:55)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
2020-11-03 14:53:29.178 9848-9848/com.example.soas I/Process: Sending signal. PID: 9848 SIG: 9
Firebase Database Structure:
Services.Java
package com.example.soas.Activities;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.soas.Adapters.ServiceAdapter;
import com.example.soas.POJO.Service;
import com.example.soas.R;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class Services extends AppCompatActivity {
RecyclerView recyclerView;
FloatingActionButton fab;
FirebaseDatabase database;
DatabaseReference reference;
ArrayList<Service> serviceList;
String user;
FirebaseAuth mAuth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_services);
database = FirebaseDatabase.getInstance();
recyclerView = findViewById(R.id.serviceRecycler);
fab = findViewById(R.id.fab);
mAuth = FirebaseAuth.getInstance();
user = mAuth.getCurrentUser().getUid();
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
database = FirebaseDatabase.getInstance();
reference = database.getReference("Services");
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Services.this, AddNewService.class);
startActivity(intent);
}
});
}
#Override
protected void onStart() {
super.onStart();
if (reference != null) {
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
serviceList = new ArrayList<>();
for (DataSnapshot ds: snapshot.getChildren()) {
if (ds.getKey().equals(user)) {
serviceList.add(ds.getValue(Service.class));
ServiceAdapter serviceAdapter = new ServiceAdapter(serviceList);
recyclerView = findViewById(R.id.serviceRecycler);
recyclerView.setAdapter(serviceAdapter);
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(Services.this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
}
Service.class(Object)
package com.example.soas.POJO;
public class Service {
public String name;
public Service() {
}
public Service(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
ServiceAdapter.java
package com.example.soas.Adapters;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.soas.POJO.Service;
import com.example.soas.R;
import java.util.ArrayList;
public class ServiceAdapter extends RecyclerView.Adapter<ServiceAdapter.MyViewHolder> {
ArrayList<Service> serviceList;
public ServiceAdapter(ArrayList<Service> serviceList) {
this.serviceList = serviceList;
}
#NonNull
#Override
public ServiceAdapter.MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.service_item,viewGroup,false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ServiceAdapter.MyViewHolder myViewHolder, int i) {
myViewHolder.name.setText(serviceList.get(i).getName());
// myViewHolder.price.setText(serviceList.get(i).getPrice());
}
#Override
public int getItemCount() {
return serviceList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView name, price;
public MyViewHolder(View view) {
super(view);
name = itemView.findViewById(R.id.vServiceName);
price = itemView.findViewById(R.id.servicePrice);
}
}
}
You're missing a for loop over the 1...4 children in your JSON. In addition: you're loading all Services, while you only need the ones for the current user, so your code is wasting bandwidth and likely less secure.
To fix both problems, you can listen one level lower in the JSON tree, and update the code on onDataChange to match:
reference.child(user).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
serviceList = new ArrayList<>();
for (DataSnapshot ds: snapshot.getChildren()) {
serviceList.add(ds.getValue(Service.class));
}
ServiceAdapter serviceAdapter = new ServiceAdapter(serviceList);
recyclerView = findViewById(R.id.serviceRecycler);
recyclerView.setAdapter(serviceAdapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(Services.this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
});

Duplication of first message key on Recycler View upon refresh

The probelm occurs when i use the swipeRefreshLayout to load all messages from database. When i refresh the recycler view it will duplicate my first key as many times as i refresh. Data is only viewed differently on recycler view, it wont affect database.
How can i stop it from displaying the first key multiple times in recycler view? Any help would be great i don't know what condition i should use to fix this.
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ServerValue;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import de.hdodenhof.circleimageview.CircleImageView;
public class MessageActivity extends AppCompatActivity {
// Initialise
private String userID;
private DatabaseReference databaseReference;
private TextView messageTitle;
private TextView lastActive;
private CircleImageView profileImg;
private Toolbar messageToolbar;
private FirebaseAuth firebaseAuth;
private String currentUser;
private EditText messageText;
private ImageButton sendMessage;
// Initialise Array list
private final List<Messages> messages_list = new ArrayList<>();
private LinearLayoutManager linearLayoutManager;
// Messages to load to and current page
private MessageAdapter messageAdapter;
private int current_page = 1;
private static final int messages_to_load = 10;
// Messages RecylerView
private RecyclerView messageView;
private SwipeRefreshLayout swipeRefreshLayout;
private int position = 0;
private String last_message ="";
private String first_message = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message);
// Setup Toolbar
messageToolbar = findViewById(R.id.message_bar);
setSupportActionBar(messageToolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowCustomEnabled(true);
// Get Database Reference
databaseReference = FirebaseDatabase.getInstance().getReference();
firebaseAuth = FirebaseAuth.getInstance();
currentUser = firebaseAuth.getCurrentUser().getUid();
// Get user ID from Intent
userID = getIntent().getStringExtra("user_ID");
String UserName = getIntent().getStringExtra("user_Name");
// getSupportActionBar().setTitle(UserName);
// Inflater Service
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View message_actionbar_view = inflater.inflate(R.layout.message_custom_imagebar,null);
actionBar.setCustomView(message_actionbar_view);
// Action bar
messageTitle = findViewById(R.id.message_bar_title);
lastActive = findViewById(R.id.message_bar_lastseen);
profileImg = findViewById(R.id.message_image);
messageText = findViewById(R.id.send_message_text);
sendMessage = findViewById(R.id.message_send_btn);
messageAdapter = new MessageAdapter(messages_list);
messageView = findViewById(R.id.Messages_recycler);
// set swipe layout
swipeRefreshLayout = findViewById(R.id.swipe_layout_message);
linearLayoutManager = new LinearLayoutManager(this);
messageView.setHasFixedSize(true);
messageView.setLayoutManager(linearLayoutManager);
messageView.setAdapter(messageAdapter);
// Call get messages method
getMessages();
// Set values
messageTitle.setText(UserName);
databaseReference.child("Users").child(userID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String onlineUser = dataSnapshot.child("online").getValue().toString();
String userImg = dataSnapshot.child("image").toString();
Timestamp timestamp = new Timestamp();
long lastSeen = Long.parseLong(onlineUser);
String lastActives = timestamp.getTimeAgo(lastSeen, getApplicationContext());
// lastActive.setText(lastActives);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
// click event on image button
sendMessage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sendMessageText();
}
});
// What happens when you swipe to refresh
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
current_page++;
position = 0;
getAllMessages();
}
});
}
// Load a number of messages
private void getAllMessages() {
DatabaseReference message_reference = databaseReference.child("Messages").child(currentUser).child(userID);
Query message_Query = message_reference.orderByKey().endAt(last_message).limitToLast(10);
message_Query.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Messages message = dataSnapshot.getValue(Messages.class);
String last_message_key = dataSnapshot.getKey();
messages_list.add(position++, message);
// Checks if position is 1
if(position == 1){
last_message = last_message_key;
}
messageAdapter.notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false);
linearLayoutManager.scrollToPositionWithOffset(10,0);
}
#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) {
}
});
}
private void getMessages() {
DatabaseReference message_reference = databaseReference.child("Messages").child(currentUser).child(userID);
Query message_Query = message_reference.limitToLast(current_page * messages_to_load);
message_Query.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Messages messages = dataSnapshot.getValue(Messages.class);
position++;
if(position == 1){
String last_message_key = dataSnapshot.getKey();
last_message = last_message_key;
first_message = last_message_key;
}
messages_list.add(messages);
messageAdapter.notifyDataSetChanged();
messageView.scrollToPosition(messages_list.size() - 1);
swipeRefreshLayout.setRefreshing(false);
}
#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) {
}
});
}
private void sendMessageText() {
String message = messageText.getText().toString();
if(!TextUtils.isEmpty(message)){
String current_User = "Messages/" + currentUser + "/" + userID;
String chat_User = "Messages/" + userID + "/" + currentUser;
DatabaseReference message_push = databaseReference.child("Messages").child(currentUser).child(userID).push();
String pushID = message_push.getKey();
Map sendMessageMap = new HashMap();
sendMessageMap.put("message", message);
sendMessageMap.put("seen", false);
sendMessageMap.put("type", "text");
sendMessageMap.put("time", ServerValue.TIMESTAMP);
sendMessageMap.put("from", currentUser);
Map sendUserMap = new HashMap();
sendUserMap.put(current_User + "/" + pushID, sendMessageMap);
sendUserMap.put(chat_User + "/" + pushID, sendMessageMap);
messageText.setText("");
databaseReference.updateChildren(sendUserMap, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(#Nullable DatabaseError databaseError, #NonNull DatabaseReference databaseReference) {
if(databaseError != null){
Log.d("CHAT_LOG", databaseError.getMessage());
}
}
});
}
}
}
It should Print Only once to recycler view, not 2 or 3 times.

Using an unspecified index

Hello StackOverflow Community, I wrote a Code to Search Users in the Firebase Database and every time I try to launch the Code it doesn't Show me the users.
In my Run log I get the following Message:
W/PersistentConnection: pc_0 - Using an unspecified index. Your data will be downloaded and filtered on the client. Consider adding '".indexOn": "username"' at users to your security and Firebase Database rules for better Performance
This is the Code which I wrote:
package com.example.ts.tsp.Fragment;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import com.example.ts.tsp.Adapter.UserAdapter;
import com.example.ts.tsp.Model1.User;
import com.example.ts.tsp.R;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class SearchFragment extends Fragment {
private RecyclerView recyclerView;
private UserAdapter userAdapter;
private List<User> mUsers;
EditText search_bar;
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
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);
mUsers = new ArrayList<>();
userAdapter = new UserAdapter(getContext(), mUsers);
recyclerView.setAdapter(userAdapter);
readUsers();
search_bar.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
searchUsers(s.toString().toLowerCase());
}
#Override
public void afterTextChanged(Editable s) {
}
});
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) {
mUsers.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
User user = snapshot.getValue(User.class);
mUsers.add(user);
}
userAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void readUsers(){
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("User");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (search_bar.getText().toString().equals("")){
mUsers.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
User user = snapshot.getValue(User.class);
mUsers.add(user);
}
userAdapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
And the Other Class:
package com.example.ts.tsp.Adapter;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentActivity;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.example.ts.tsp.Fragment.ProfileFragment;
import com.example.ts.tsp.Model1.User;
import com.example.ts.tsp.R;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.List;
import de.hdodenhof.circleimageview.CircleImageView;
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.Viewholder>{
private Context mContext;
private List<User> mUsers;
private FirebaseUser firebaseUser;
public UserAdapter(Context mContext, List<User> mUsers) {
this.mContext = mContext;
this.mUsers = mUsers;
}
#NonNull
#Override
public Viewholder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(mContext) .inflate(R.layout.user_item, viewGroup, false);
return new UserAdapter.Viewholder(view);
}
#Override
public void onBindViewHolder(#NonNull final Viewholder viewHolder, int i) {
firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
final User user = mUsers.get(i);
viewHolder.btn_follow.setVisibility(View.VISIBLE);
viewHolder.username.setText(user.getUsername());
viewHolder.fullname.setText(user.getFullname());
Glide.with(mContext) .load(user.getImageurl()) .into(viewHolder.image_Profile);
isFollowing(user.getId(), viewHolder.btn_follow);
if (user.getId().equals(firebaseUser.getUid())){
viewHolder.btn_follow.setVisibility(View.GONE);
}
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences.Editor editor = mContext.getSharedPreferences( "PREFS", Context.MODE_PRIVATE) .edit();
editor.putString("profileid", user.getId());
editor.apply();
((FragmentActivity)mContext).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new ProfileFragment()).commit();
}
});
viewHolder.btn_follow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (viewHolder.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);
} 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();
}
}
});
}
#Override
public int getItemCount() {
return 0;
}
public class Viewholder extends RecyclerView.ViewHolder{
public TextView username;
public TextView fullname;
public CircleImageView image_Profile;
public Button btn_follow;
public Viewholder(#NonNull 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) {
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) {
}
});
}
}
I hope someone can help you
Best Regard Tim schmitt
For using orderby:
FirebaseDatabase.getInstance().getReference("Users").orderByChild("username")
you have to add index on the specific field, update your rules in the Firebase Database console.
{
"rules": {
// By default all nodes are private
".read":false,
".write":false,
"Users": {
".read": true,
".write": "(auth!=null)",
".indexOn" : ["username"]
}
}
}
I would recommend using Cloud Firestore instead of Firebase Realtime Database.

Show data from Firebase in RecyclerView on Android

I currently have implemented RecyclerView, but my CarView does not show the data.
These are my current data in Firebase:
But the RecyclerView shows all three CardViews, but without the records:
These are the files I'm using:
DomiciliarySearchFragment.java
import android.os.Bundle;
import android.os.AsyncTask;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.didierzuniga.domix.R;
import com.didierzuniga.domix.adapter.OrderAdapterRecyclerView;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.HashMap;
import butterknife.Bind;
import butterknife.ButterKnife;
/**
* A simple {#link Fragment} subclass.
*/
public class DomiciliarySearchFragment extends Fragment {
#Bind(R.id.recycler_order) RecyclerView recyclerView;
public DomiciliarySearchFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
super.onCreate(savedInstanceState);
View view = inflater.inflate(R.layout.fragment_domiciliary_search, container, false);
showToolbar(getResources().getString(R.string.tab_search), true, view);
ButterKnife.bind(this, view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
new GetDataFromFirebase().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
// Read from the database
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("order");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
HashMap<String, String> values = (HashMap<String, String>) dataSnapshot.getValue();
recyclerView.setAdapter(new OrderAdapterRecyclerView(values));
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
System.out.println("Failed to read value." + error.toException());
}
});
return view;
}
private class GetDataFromFirebase extends AsyncTask<Void,Void,Boolean>{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Boolean doInBackground(Void... voids) {
return false;
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
}
}
public void showToolbar(String tittle, boolean upButton, View view){
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(tittle);
((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(upButton);
}
}
OrderAdapterRecyclerView.java
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.didierzuniga.domix.R;
import java.util.HashMap;
import java.util.Map;
public class OrderAdapterRecyclerView extends RecyclerView.Adapter<OrderAdapterRecyclerView.ViewHolder>{
private HashMap<String, String> values;
public OrderAdapterRecyclerView(HashMap<String, String> values) {
this.values = values;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview_order,parent,false));
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.fromm.setText(values.get(position));
holder.too.setText(values.get(position));
holder.moneyToPayy.setText(values.get(position));
}
#Override
public int getItemCount() {
return values.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView fromm;
private TextView too;
private TextView moneyToPayy;
ViewHolder(View itemView) {
super(itemView);
fromm = (TextView) itemView.findViewById(R.id.from);
too = (TextView) itemView.findViewById(R.id.to);
moneyToPayy = (TextView) itemView.findViewById(R.id.moneyToPay);
}
}
}
Model: Order.java
public class Order {
public String uid;
public String oFrom;
public String oTo;
public String oHeader;
public String oDescription;
public String oMoneyToPay;
public String oAuthor;
public boolean completed;
public Order(){
}
public Order(String oFrom, String oTo, String oHeader, String oDescription, String oMoneyToPay, String oAuthor) {
this.oFrom = oFrom;
this.oTo = oTo;
this.oHeader = oHeader;
this.oDescription = oDescription;
this.oMoneyToPay = oMoneyToPay;
this.oAuthor = oAuthor;
this.completed = false;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getoFrom() {
return oFrom;
}
public void setoFrom(String oFrom) {
this.oFrom = oFrom;
}
public String getoTo() {
return oTo;
}
public void setoTo(String oTo) {
this.oTo = oTo;
}
public String getoHeader() {
return oHeader;
}
public void setoHeader(String oHeader) {
this.oHeader = oHeader;
}
public String getoDescription() {
return oDescription;
}
public void setoDescription(String oDescription) {
this.oDescription = oDescription;
}
public String getoMoneyToPay() {
return oMoneyToPay;
}
public void setoMoneyToPay(String oMoneyToPay) {
this.oMoneyToPay = oMoneyToPay;
}
public String getoAuthor() {
return oAuthor;
}
public void setoAuthor(String oAuthor) {
this.oAuthor = oAuthor;
}
public boolean isCompleted() {
return completed;
}
public void setCompleted(boolean completed) {
this.completed = completed;
}
}
¿What I need to do to be able to display the registers in each CardView?
Thank you!
In DomiciliarySearchFragment.java /onDataChange,
Can you confirm that hashmap has been correctly populated?
I had a similar problem, but the reason was that the data was not stored correctly in the collection
Thanks uguboz, I should have use dataSnapshot.getChildren(), and get all the records one by one in a loop
rv = (RecyclerView) view.findViewById(R.id.recycler_order);
rv.setLayoutManager(new LinearLayoutManager(getContext()));
orders = new ArrayList<>();
FirebaseDatabase database = FirebaseDatabase.getInstance();
adapter = new OrderAdapter(orders);
rv.setAdapter(adapter);
database.getReference().child("order").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
orders.removeAll(orders);
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Order order = snapshot.getValue(Order.class);
orders.add(order);
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Thank you everyone.

Categories

Resources