I'm showing data from a Firebase Firestore collection, the app worked fine while but when I update data to the collection from other device (I got an Arduino with sensors connected to a PC that executes a Python script to transform the serial data to JSON and then I update that data on the Firestore collection, all the back end of these functionality works perfectly. My problem it's the Java on Android.
I already search for solutions on this forum and It seems like something doesn't work with the Adapter, the RecyclerView and the "notifyDataSetChanged();" None of the current solutions worked for me or maybe I just don't know how to implement them on my project.
This is my model
public class Monitor {
String alias, placa, temp, acid;
public Monitor(){}
public Monitor(String alias, String placa, String temp, String acid) {
this.alias = alias;
this.placa = placa;
this.temp = temp;
this.acid = acid;
}
public String getAlias() {
return alias;
}
public void setAlias(String alias) {
this.alias = alias;
}
public String getPlaca() {
return placa;
}
public void setPlaca(String placa) {
this.placa = placa;
}
public String getTemp() {
return temp;
}
public void setTemp(String temp) {
this.temp = temp;
}
public String getAcid() {
return acid;
}
public void setAcid(String acid) {
this.acid = acid;
}
}
The adapter
public class MonitorAdapter extends FirestoreRecyclerAdapter<Monitor, MonitorAdapter.ViewHolder> {
private FirebaseFirestore mFirestore = FirebaseFirestore.getInstance();
Activity activity;
/**
* Create a new RecyclerView adapter that listens to a Firestore Query. See {#link
* FirestoreRecyclerOptions} for configuration options.
*
* #param options
*/
public MonitorAdapter(#NonNull FirestoreRecyclerOptions<Monitor> options, Activity activity) {
super(options);
this.activity = activity;
}
#Override
protected void onBindViewHolder(#NonNull ViewHolder holder, int position, #NonNull Monitor model) {
DocumentSnapshot documentSnapshot = getSnapshots().getSnapshot(holder.getAbsoluteAdapterPosition());
final String id = documentSnapshot.getId();
holder.alias.setText(model.getAlias());
holder.temp.setText(model.getTemp());
holder.acid.setText(model.getAcid());
holder.btn_edit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(activity, VincularPlaca.class);
i.putExtra("id_placa",id);
activity.startActivity(i);
}
});
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_monitor_single,parent,false);
return new ViewHolder(view);
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView alias, temp, acid;
Button btn_edit;
public ViewHolder(#NonNull View itemView) {
super(itemView);
alias = itemView.findViewById(R.id.alias);
temp = itemView.findViewById(R.id.temp);
acid = itemView.findViewById(R.id.acid);
btn_edit = itemView.findViewById(R.id.btn_edit);
}
}
}
And my MainActivity
public class MainActivity extends AppCompatActivity {
Button btn_add, btn_exit;
RecyclerView mRecycler;
MonitorAdapter mAdapter;
FirebaseFirestore mFirestore;
FirebaseAuth mAuth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFirestore = FirebaseFirestore.getInstance();
mRecycler = findViewById(R.id.recyclerViewSingle);
mRecycler.setLayoutManager(new LinearLayoutManager(this));
Query query = mFirestore.collection("dispositivos");
FirestoreRecyclerOptions<Monitor> firestoreRecyclerOptions =
new FirestoreRecyclerOptions.Builder<Monitor>().setQuery(query,Monitor.class).build();
mAdapter = new MonitorAdapter(firestoreRecyclerOptions, this);
mAdapter.notifyDataSetChanged();
mRecycler.setAdapter(mAdapter);
btn_add = findViewById(R.id.btn_add);
btn_exit = findViewById(R.id.btn_close);
btn_add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this,VincularPlaca.class));
}
});
btn_exit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this,LoginActivity.class));
mAuth.signOut();
}
});
}
#Override
protected void onStart() {
super.onStart();
mAdapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
mAdapter.stopListening();
}
}
class ExampleViewModel : ViewModel() {
var mFirestore : FirebaseFirestore? = null
private val _list = MutableLiveData<FirestoreRecyclerOptions<Monitor>>()
val list: LiveData<FirestoreRecyclerOptions<Monitor>> = _list
init{
mFirestore = FirebaseFirestore.getInstance()
list.value= FirestoreRecyclerOptions.Builder<Monitor>().setQuery(mFirestore!!.collection("dispositivos"),Monitor::class.java).build()
}
}
The problem has solved fixing the AndroidManifest Permissions and outside the code on the Firebase Firestore console, the attribute was supose to be an string but it recieves an int.
Related
The recycler view only shows the recent add i.e the single element which is newly added, and the rest of the activity is blank, Also whenever I switch fragments and visit again the main fragment it shows all data?
Place to display data and set Adapter:
public class HomeFragment extends Fragment {
private RecyclerView recyclerView;
private List<BlogPost> blogList;
private FirebaseFirestore firestore;
private FirebaseDatabase database;
private DatabaseReference reference;
private BlogPostAdapter adapter;
public HomeFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
blogList = new ArrayList<>();
firestore = FirebaseFirestore.getInstance();
recyclerView = (RecyclerView)view.findViewById(R.id.post_list_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(view.getContext()));
EventChangeListener();
adapter = new BlogPostAdapter(blogList);
recyclerView.setAdapter(adapter);
return view;
}
public void EventChangeListener() {
Query firstQuery = firestore.collection("Posts").orderBy("TimeStamp",Query.Direction.ASCENDING);
firstQuery.addSnapshotListener(new EventListener<QuerySnapshot>() {
#SuppressLint("NotifyDataSetChanged")
#Override
public void onEvent(#Nullable QuerySnapshot value, #Nullable FirebaseFirestoreException error) {
if(error!=null)
{
Log.e("Firestore Error",error.getMessage());
return;
}
blogList.clear();
for(DocumentChange doc : value.getDocumentChanges())
{
if(doc.getType()== DocumentChange.Type.ADDED)
{
String blogPostId = doc.getDocument().getId();
QueryDocumentSnapshot post = doc.getDocument();
BlogPost blogPost = new BlogPost();
Map<String, Object> s = post.getData();
int[] likeCnt = {0};
blogPost.setPost_txt((String) s.get("Post_Content"));
DocumentSnapshot.ServerTimestampBehavior behavior = ESTIMATE;
blogPost.setTimestamp(post.getDate("TimeStamp", behavior));
blogPost.setUser_id((String) s.get("User"));
blogList.add(0,blogPost.withId(blogPostId));
}
}
adapter.notifyDataSetChanged();
}
});
}
**/*Adapter Code*/**
public class BlogPostAdapter extends RecyclerView.Adapter<BlogPostAdapter.ViewHolder> {
private List<BlogPost> blog_lists;
private FirebaseFirestore firestore;
private FirebaseAuth mAuth;
private Context context;
public BlogPostAdapter(List<BlogPost> lc)
{
this.blog_lists = lc;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
mAuth = FirebaseAuth.getInstance();
firestore = FirebaseFirestore.getInstance();
context = parent.getContext();
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_post_view,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, #SuppressLint("RecyclerView") int position) {
String blogPostId = blog_lists.get(position).blogPostId;
String sc = blog_lists.get(position).getPost_txt();
holder.postContent.setText(sc);
String currentUserId = mAuth.getCurrentUser().getUid();
long millisecond = blog_lists.get(position).getTimestamp().getTime();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MMM d,yyyy");
String dateString = simpleDateFormat.format(millisecond);
holder.date.setText(dateString);
firestore.collection("Posts/"+blogPostId+"/Likes").addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot value, #Nullable FirebaseFirestoreException error) {
if(!value.isEmpty())
{
int count = value.size();
holder.updateLikes(count);
}
else {
holder.updateLikes(0);
}
}
});
firestore.collection("Posts/" + blogPostId + "/Likes").document(currentUserId).addSnapshotListener(new EventListener<DocumentSnapshot>() {
#SuppressLint("UseCompatLoadingForDrawables")
#Override
public void onEvent(#Nullable DocumentSnapshot value, #Nullable FirebaseFirestoreException error) {
if (value.exists()) {
holder.likeBtn.setImageDrawable(context.getDrawable(R.drawable.action_liked));
} else {
holder.likeBtn.setImageDrawable(context.getDrawable(R.drawable.action_likebutton));
}
}
});
holder.likeBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
firestore.collection("Posts/"+blogPostId+"/Likes").document(currentUserId).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if(!task.getResult().exists()){
Map<String,Object> mp = new HashMap<>();
mp.put("TimeStamp", FieldValue.serverTimestamp());
firestore.collection("Posts/"+blogPostId+"/Likes").document(currentUserId).set(mp);
}
else
{
firestore.collection("Posts/"+blogPostId+"/Likes")
.document(currentUserId).delete();
}
}
});
}
});
}
#Override
public int getItemCount() {
return blog_lists.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
private TextView postContent,date,likeCnt;
private ImageView likeBtn;
public ViewHolder(#NonNull View itemView) {
super(itemView);
postContent = (TextView) itemView.findViewById(R.id.post_content);
date = (TextView) itemView.findViewById(R.id.date);
likeBtn = (ImageView) itemView.findViewById(R.id.like_btn);
likeCnt = (TextView) itemView.findViewById(R.id.likes_cnt);
}
public void updateLikes(int count)
{
likeCnt.setText(count+" Likes");
}
}
}
**// Model Class //***
public class BlogPost extends BlogPostId {
public String user_id,post_txt;
public Date TimeStamp;
int like_count;
public BlogPost(String post_txt)
{
this.post_txt = post_txt;
}
public BlogPost()
{
}
public BlogPost(String user_id, String post_txt,Date timestamp) {
this.user_id = user_id;
this.post_txt = post_txt;
this.TimeStamp = timestamp;
}
public BlogPost(String user_id, String post_txt, Date timeStamp, int like_count) {
this.user_id = user_id;
this.post_txt = post_txt;
TimeStamp = timeStamp;
this.like_count = like_count;
}
public void setLike_count(int like_count) {
this.like_count = like_count;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id)
{
this.user_id = user_id;
}
public String getPost_txt() {
return post_txt;
}
public void setPost_txt(String post_txt) {
this.post_txt = post_txt;
}
public Date getTimestamp() {
return TimeStamp;
}
public void setTimestamp(Date timestamp) {
this.TimeStamp = timestamp;
}
public int getLike_count() {
return like_count;
}
}
**// Main Activity //**
public class MainActivity extends AppCompatActivity {
private androidx.appcompat.widget.Toolbar mainToolbar;
private ImageView addPost_btn;
private BottomNavigationView main_bottom_nav_view;
private FirebaseAuth mAuth;
private HomeFragment homeFragment;
private NotificationFragment notificationFragment;
private AccountFragment accountFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(isNetworkAvailable())
{
Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(this, "Connection Unavailable", Toast.LENGTH_SHORT).show();
}
mAuth = FirebaseAuth.getInstance();
//Bottom navigation bar
main_bottom_nav_view = findViewById(R.id.mainBottomNav);
//Fragment
homeFragment = new HomeFragment();
notificationFragment = new NotificationFragment();
accountFragment = new AccountFragment();
//Post Button
addPost_btn = (ImageView) findViewById(R.id.addPostBtn);
replaceFragment(homeFragment);
addPost_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent post_Intent = new Intent(MainActivity.this,NewPostActivity.class);
startActivity(post_Intent);
}
});
main_bottom_nav_view.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch(item.getItemId())
{
case R.id.bottom_home:
replaceFragment(homeFragment);
return true;
case R.id.bottom_post:
replaceFragment(notificationFragment);
return true;
case R.id.bottom_acc:
replaceFragment(accountFragment);
return true;
default:
return false;
}
}
});
}
#Override
protected void onStart() {
super.onStart();
FirebaseUser currUser = FirebaseAuth.getInstance().getCurrentUser();
if(currUser==null)
{
sendToLogin();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu,menu);
return true;
}
private void sendToLogin() {
Intent login_Intent = new Intent(MainActivity.this,Login_Activity.class);
startActivity(login_Intent);
finish();
}
private void replaceFragment(Fragment newFragment)
{
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.main_container,newFragment);
fragmentTransaction.commit();
}
private boolean isNetworkAvailable() {
try{
ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = null;
if(manager!=null)
{
networkInfo = manager.getActiveNetworkInfo();
}
return networkInfo!=null && networkInfo.isConnected();
}
catch (NullPointerException e)
{
return false;
}
}
}
**// Adding New Data to Firebase FireStore**
public class NewPostActivity extends AppCompatActivity {
private EditText post_txt;
private ImageView post_btn;
private ProgressBar new_post_progress;
private StorageReference storageReference;
private FirebaseFirestore firestore;
private FirebaseAuth firebaseAuth;
private String currUser;
private Uri post_txtUri=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_post);
post_txt = (EditText) findViewById(R.id.post_txt);
post_btn = (ImageView) findViewById(R.id.post_btn);
firebaseAuth = FirebaseAuth.getInstance();
currUser = firebaseAuth.getCurrentUser().getEmail();
new_post_progress = (ProgressBar) findViewById(R.id.new_post_progress);
storageReference = FirebaseStorage.getInstance().getReference().child("Post_Contents");
firestore = FirebaseFirestore.getInstance();
post_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String text = post_txt.getText().toString();
if(!TextUtils.isEmpty(text))
{
new_post_progress.setVisibility(View.VISIBLE);
String randomName = FieldValue.serverTimestamp().toString();
Map<String,Object> postMap = new HashMap<>();
postMap.put("Post_Content",text);
postMap.put("User",currUser);
postMap.put("TimeStamp",FieldValue.serverTimestamp());
firestore.collection("Posts").add(postMap).addOnCompleteListener(new OnCompleteListener<DocumentReference>() {
#Override
public void onComplete(#NonNull Task<DocumentReference> task) {
new_post_progress.setVisibility(View.INVISIBLE);
if(task.isSuccessful())
{
Toast.makeText(NewPostActivity.this,"Posted Successfully",Toast.LENGTH_SHORT).show();
Intent mainPage = new Intent(NewPostActivity.this,MainActivity.class);
startActivity(mainPage);
finish();
}
else
{
Toast.makeText(NewPostActivity.this,"Error Occurred",Toast.LENGTH_SHORT).show();
}
}
});
}
else
{
Toast.makeText(NewPostActivity.this,"Error in posting",Toast.LENGTH_SHORT).show();
}
// firestore.collection("Posts").document().update("TimeStamp",FieldValue.serverTimestamp());
}
});
}
}
I use a NewPostActivity to post the data in firebase Firestore by creating a collections and retrieving the data in recycler view format as usual, but whenever I retrieve data from firebase and add it to arraylist and display in recyclerView it only shows the newly added element at first and then when I switch to another fragment and come back to homeFragment it shows all the post neatly. I tried finding solutions on youtube but couldn't find any.
i want to click in my recyclerview and open a new activity to show the datails. Ultil now i
have accomplished to open the activity and show the values "interno" and "siniiga" with the next intent. how can i get "madre and padre" values from firebase? applying the method to add father and mother, then I will use it for the rest of the values that the xml shows. excuse my horrible code. if someone know a different method, let me know
attached code and images.
Main Activity
RecyclerView rv;
List<cow> vacas;
adapter adapter;
ImageButton mbuttoninf;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rv = (RecyclerView) findViewById(R.id.recyclerViewGirdView);
rv.setLayoutManager(new LinearLayoutManager(this));
vacas = new ArrayList<>();
FirebaseDatabase database = FirebaseDatabase.getInstance();
adapter = new adapter(vacas);
rv.setAdapter(adapter);
database.getReference("Vacas").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
vacas.removeAll(vacas);
for (DataSnapshot snapshot1 :
snapshot.getChildren()) {
cow vaca = snapshot1.getValue(cow.class);
vacas.add(vaca);
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
cow
String interno;
String siniiga;
String ulr;
String madre;
String padre;
public cow() {
}
public cow(String interno, String siniiga, String ulr, String madre, String padre) {
this.interno = interno;
this.siniiga = siniiga;
this.ulr = ulr;
this.madre = madre;
this.padre = padre;
}
public String getInterno() {
return interno;
}
public void setInterno(String interno) {
this.interno = interno;
}
public String getSiniiga() {
return siniiga;
}
public void setSiniiga(String siniiga) {
this.siniiga = siniiga;
}
public String getUlr() {
return ulr;
}
public void setUlr(String ulr) {
this.ulr = ulr;
}
public String getMadre() {
return madre;
}
public void setMadre(String madre) {
this.madre = madre;
}
public String getPadre() {
return padre;
}
public void setPadre(String padre) {
this.padre = padre;
}
}
Adapter
List<cow> vacas;
Context context;
public adapter(List<cow> vacas) {
this.vacas = vacas;
}
#NonNull
#Override
public cowviewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_vaca,parent,false);
cowviewHolder holder = new cowviewHolder(v);
return holder;
}
#Override
public void onBindViewHolder(#NonNull final cowviewHolder holder, final int position) {
final cow vacaslist = vacas.get(position);
holder.textViewinterno.setText(String.valueOf(vacaslist.interno));
holder.textViewsiniiga.setText(String.valueOf(vacaslist.siniiga));
Glide.with(holder.imageviewrec.getContext()).load(vacaslist.getUlr()).into(holder.imageviewrec);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent=new Intent(v.getContext(),detailactivity.class);
intent.putExtra("keyint", vacaslist.getInterno());
intent.putExtra("keysin", vacaslist.getSiniiga());
v.getContext().startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return vacas.size();
}
public static class cowviewHolder extends RecyclerView.ViewHolder {
TextView textViewinterno, textViewsiniiga, tvmadre, tvpadre;
ImageView imageviewrec;
public cowviewHolder(#NonNull View itemView) {
super(itemView);
textViewinterno = itemView.findViewById(R.id.interno);
textViewsiniiga = itemView.findViewById(R.id.siniiga);
imageviewrec = itemView.findViewById(R.id.imgrec);
tvmadre = itemView.findViewById(R.id.tvmadre);
tvpadre = itemView.findViewById(R.id.tvpadre);
}
}
detailsactivity
TextView textView;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.informationfire);
TextView tvinterno = (TextView) findViewById(R.id.tvinterno);
TextView tvsiniiga = (TextView) findViewById(R.id.tvsiniiga);
String vinterno = "";
String vsiniiga = "";
Bundle extras = getIntent().getExtras();
if (extras !=null);
vinterno = extras.getString("keyint");
vsiniiga = extras.getString("keysin");
tvinterno.setText(vinterno);
tvsiniiga.setText(vsiniiga);
}
}
firebase
enter image description here
and the xml for details
enter image description here
when you are getting data from firebase you saving that data in a Object and then add that object to list, so your list contains objects , so you can pass through the intents same way as you are doing others.
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent=new Intent(v.getContext(),detailactivity.class);
intent.putExtra("keyint", vacaslist.getInterno());
intent.putExtra("keysin", vacaslist.getSiniiga());
intent.putExtra("madre", vacaslist.getMadre());
intent.putExtra("padre", vacaslist.getPadre());
v.getContext().startActivity(intent);
}
});
I'm trying to use OnItemClick to display details in a user profile page and I still have this error:
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:437)
at fr.ousoft.suiviemedsbox.ScrollingActivity.OnItemClick(**ScrollingActivity.java:102**)
at fr.ousoft.suiviemedsbox.UsersAdapter$AdapterVH$1.onClick(**UsersAdapter.java:115**)
Here is my Activity code
public class ScrollingActivity extends AppCompatActivity implements UsersAdapter.OnItemClickListener {
public static final String EXTRA_CREATOR_NOM = "Nom";
public static final String EXTRA_CREATOR_PRENOM = "Prenom";
public static final String EXTRA_CREATOR_TEL = "Tel";
public static final String EXTRA_CREATOR_EMAIL = "Email";
public static final String EXTRA_CREATOR_ETABLISSEMENT = "Etablissement";
public static final String EXTRA_CREATOR_TYPE = "Type";
public static final String EXTRA_CREATOR_ACTIVE = "Active";
RecyclerView recyclerView;
ApiInterface apiInterface;
UsersAdapter usersAdapter;
ArrayList<User> mListe = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scrolling);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
CollapsingToolbarLayout toolBarLayout = (CollapsingToolbarLayout) findViewById(R.id.toolbar_layout);
toolBarLayout.setTitle(getTitle());
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(ScrollingActivity.this, RegisterActivity.class);
startActivity(intent);
}
});
recyclerView = findViewById(R.id.recyclerViewList);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
usersAdapter = new UsersAdapter();
fetchUsers();
}
public void fetchUsers(){
apiInterface = ApiClient.getRetrofitInstance().create(ApiInterface.class);
Call<List<User>> call = apiInterface.getAllUsers();
call.enqueue(new Callback<List<User>>() {
#Override
public void onResponse(Call<List<User>> call, Response<List<User>> response) {
if (response.isSuccessful()){
List<User> users = response.body();
usersAdapter.setData(users);
usersAdapter.setOnItemClickListener(ScrollingActivity.this);
recyclerView.setAdapter(usersAdapter);
}
}
#Override
public void onFailure(Call<List<User>> call, Throwable t) {
Log.e("success", t.getLocalizedMessage());
}
});
}
#Override
public void OnItemClick(int position) {
Intent detailIntent = new Intent(this,DetailActivity.class);
User clickedUser = mListe.get(position);
detailIntent.putExtra(EXTRA_CREATOR_NOM, clickedUser.getNom());
detailIntent.putExtra(EXTRA_CREATOR_PRENOM, clickedUser.getPrenom());
detailIntent.putExtra(EXTRA_CREATOR_TEL, clickedUser.getTel());
detailIntent.putExtra(EXTRA_CREATOR_EMAIL, clickedUser.getEmail());
detailIntent.putExtra(EXTRA_CREATOR_ETABLISSEMENT, clickedUser.getEtablissement());
detailIntent.putExtra(EXTRA_CREATOR_TYPE, clickedUser.getType());
detailIntent.putExtra(EXTRA_CREATOR_ACTIVE, clickedUser.getActive());
startActivity(detailIntent);
}
}
Adapter:
public class UsersAdapter extends RecyclerView.Adapter<UsersAdapter.AdapterVH>{
private List<User> userList;
private Context context;
private OnItemClickListener mListener;
public interface OnItemClickListener {
void OnItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
public UsersAdapter(){
}
public void setData(List<User> userList){
this.userList = userList;
notifyDataSetChanged();
}
#NonNull
#Override
public AdapterVH onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
return new UsersAdapter.AdapterVH(LayoutInflater.from(context).inflate(R.layout.item_list,parent,false));
}
#SuppressLint("ResourceAsColor")
#Override
public void onBindViewHolder(#NonNull AdapterVH holder, int position) {
User user = userList.get(position);
String nom = user.getNom();
String email = user.getEmail();
String etab = user.getEtablissement();
String active = user.getActive();
String prenom = user.getPrenom();
holder.txtNom.setText(nom);
if (nom == null) {
holder.txtNom.setText("Aucun Nom");
}
holder.txtEmail.setText(email);
if (email == null) {
holder.txtEmail.setText("Aucun Email");
}
holder.txtEttab.setText(etab);
if (etab == null) {
holder.txtEttab.setText("Aucun Etablissement");
}
holder.txtPrenom.setText(prenom);
if (prenom == null) {
holder.txtPrenom.setText("Aucun Prenom");
}
if (active == null) {
holder.ActiveDesactive.setText(R.string.desact);
}else {
holder.ActiveDesactive.setText(R.string.activ);
}
}
#Override
public int getItemCount() {
return userList.size();
}
public class AdapterVH extends RecyclerView.ViewHolder{
TextView txtNom;
TextView txtPrenom;
TextView txtEmail;
TextView txtEttab;
Button ActiveDesactive;
public AdapterVH(#NonNull View itemView) {
super(itemView);
txtNom = itemView.findViewById(R.id.NomUser);
txtPrenom = itemView.findViewById(R.id.PrenomUser);
txtEmail = itemView.findViewById(R.id.EmailUser);
txtEttab = itemView.findViewById(R.id.EtabUser);
ActiveDesactive = itemView.findViewById(R.id.ActiveDesavtive);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mListener != null){
int positions = getAdapterPosition();
if (positions != RecyclerView.NO_POSITION){
mListener.OnItemClick(positions);
}
}
}
});
}
}
}
You never fill mListe with any content. If you search for mListe. the only match you get is mListe.get. You have no invocations of mListe.add or mListe.addAll. What you do instead is set a list from a response directly into the adapter:
if (response.isSuccessful()){
// Here is the error
List<User> users = response.body();
usersAdapter.setData(users);
usersAdapter.setOnItemClickListener(ScrollingActivity.this);
recyclerView.setAdapter(usersAdapter);
}
What should be done instead is the following:
Clear mListe from any previous content;
Fill with new content;
Set new data to the adapter.
if (response.isSuccessful()){
mListe.clear();
mListe.addAll(response.body());
usersAdapter.setData(mListe);
}
I have removed a few lines from this if-statement and moved them into the onCreate. They should be called only once, there is no benefit setting the same adapter and click listener if you call fetchUsers() again.
#Override
protected void onCreate(Bundle savedInstanceState) {
...
usersAdapter = new UsersAdapter();
usersAdapter.setOnItemClickListener(this);
recyclerView.setAdapter(usersAdapter);
fetchUsers();
}
you are not adding anything in ArrayList<User> mListe = new ArrayList<>();
you should add values before implementing any action,
try this
if (response.isSuccessful()){
List<User> users = response.body();
mListe.addAll(users);
usersAdapter.setData(users);
usersAdapter.setOnItemClickListener(ScrollingActivity.this);
recyclerView.setAdapter(usersAdapter);
}
SearchPage where I search the books from firebase
public class SearchPage extends AppCompatActivity {
EditText searchbar;
RecyclerView recyclerView;
DatabaseReference reference;
ArrayList<String> BookNameList;
ArrayList<String> AuthorNameList;
ArrayList<String> PicList;
ArrayList<String> PublisherList;
ArrayList<String> Shelfnols;
ArrayList<String> Desc;
SearchAdapter searchAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_page);
searchbar = (EditText) findViewById(R.id.searchbar);
reference = FirebaseDatabase.getInstance().getReference();
reference.keepSynced(true);
recyclerView = (RecyclerView) findViewById(R.id.rv);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
BookNameList = new ArrayList<>();
PublisherList = new ArrayList<>();
AuthorNameList = new ArrayList<>();
Shelfnols = new ArrayList<>();
PicList = new ArrayList<>();
Desc=new ArrayList<>();
searchbar.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) {
}
#Override
public void afterTextChanged(Editable s) {
if (!s.toString().isEmpty()) {
setAdapter(s.toString());
}
else{
BookNameList.clear();
AuthorNameList.clear();
PicList.clear();
PublisherList.clear();
Shelfnols.clear();
Desc.clear();
}
}
private void setAdapter(final String searchedString) {
reference.child("books").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
BookNameList.clear();
AuthorNameList.clear();
PicList.clear();
PublisherList.clear();
Shelfnols.clear();
Desc.clear();
int counter=0;
for(DataSnapshot snapshot:dataSnapshot.getChildren()){
String uid = snapshot.getKey();
Log.i(uid,"ids");
String desc = snapshot.child("Desc").getValue(String.class);
String bookname = snapshot.child("bookname").getValue(String.class);
String author = snapshot.child("author").getValue(String.class);
String image = snapshot.child("image").getValue(String.class);
String publisher = snapshot.child("Publisher").getValue(String.class);
String shelfno = snapshot.child("Shelf_no").getValue(String.class);
try {
if (bookname.toLowerCase().contains(searchedString.toLowerCase())) {
BookNameList.add(bookname);
AuthorNameList.add(author);
PublisherList.add(publisher);
Shelfnols.add(shelfno);
PicList.add(image);
Desc.add(desc);
counter++;
} else if (author.toLowerCase().contains(searchedString.toLowerCase())) {
BookNameList.add(bookname);
AuthorNameList.add(author);
PublisherList.add(publisher);
Shelfnols.add(shelfno);
PicList.add(image);
Desc.add(desc);
counter++;
}
}
catch (Exception e){
Toast.makeText(getApplicationContext(),"not found",Toast.LENGTH_LONG).show();
}
if(counter==15){
break;
}
SearchAdapter searchAdapter = new SearchAdapter(SearchPage.this, BookNameList, AuthorNameList, PicList, PublisherList, Shelfnols);
recyclerView.setAdapter(searchAdapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
});
}
this the adapter class SearchAdapter where I am getting the adapter position on click
public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchViewHolder> {
final public String id="bookname";
Context context;
ArrayList<String> BookNameList;
ArrayList<String> AuthorNameList;
ArrayList<String> PicList;
ArrayList<String> PublisherList;
ArrayList<String> Shelfnols;
LinearLayout booklayout;
DatabaseReference reference;
class SearchViewHolder extends RecyclerView.ViewHolder{
ImageView bookimage;
TextView bookname, authorname,publisher,shelfno;
public SearchViewHolder(#NonNull View itemView) {
super(itemView);
bookimage = itemView.findViewById(R.id.Bookimg);
bookname = itemView.findViewById(R.id.BookName);
authorname = itemView.findViewById(R.id.AuthorName);
publisher = itemView.findViewById(R.id.Publications);
shelfno = itemView.findViewById(R.id.Shelfno);
booklayout=itemView.findViewById(R.id.LinLayout);
reference = FirebaseDatabase.getInstance().getReference();
reference.keepSynced(true);
}
}
public SearchAdapter(Context context, ArrayList<String> bookNameList, ArrayList<String> authorNameList, ArrayList<String> picList,ArrayList<String> publisherList,ArrayList<String> shelfnols) {
this.context = context;
BookNameList = bookNameList;
AuthorNameList = authorNameList;
PicList = picList;
PublisherList=publisherList;
Shelfnols=shelfnols;
}
#NonNull
#Override
public SearchAdapter.SearchViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.activity_search_layout,parent,false);
return new SearchAdapter.SearchViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull SearchViewHolder holder, final int position) {
holder.bookname.setText(BookNameList.get(position));
holder.authorname.setText(AuthorNameList.get(position));
holder.publisher.setText(PublisherList.get(position));
holder.shelfno.setText(Shelfnols.get(position));
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context,"clicked "+position,Toast.LENGTH_LONG).show();
Intent i = new Intent(context,Bookdetailslayout.class);
context.startActivity(i);
}
});
Glide.with(context).asBitmap().load(PicList.get(position)).placeholder(R.mipmap.ic_launcher_round).into(holder.bookimage);
}
#Override
public int getItemCount() {
return BookNameList.size();
}
this is my new activity where i want the book details to be shown
public class Bookdetailslayout extends SearchPage {
DatabaseReference reference;
TextView bookname,author,publisher,desc,location;
ImageView image;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bookdetailslayout);
image=(ImageView)findViewById(R.id.img) ;
bookname = (TextView)findViewById(R.id.bkname);
author = (TextView) findViewById(R.id.aname);
publisher = (TextView) findViewById(R.id.pname);
desc = (TextView) findViewById(R.id.bkdescription);
location = (TextView) findViewById(R.id.bklocation);
String Bname=getIntent().getStringExtra("bookname");
Log.i(Bname, "onCreate: ");
DatabaseReference databaseReference=FirebaseDatabase.getInstance().getReference().child("books");
}
till now I was able to set onclick to new activity and get the position of the click as item 1,2,etc...how do I use this position to get data from firebase to the new activity
create interface
public interface SetclickListener {
public void getposition(int position);
}
inside adapter create constructor
SetclickListener setclicklistener;
public SetclickListener getSetclick(Context context) {
this.context=context;
return setclicklistener;
}
public void setclicklistener(SetclickListener setclickListener){
setclicklistener=setclickListener;
}
get selected position
setclicklistener.getposition(getAdapterPosition());
then you can implement inside SearchPage activity then you can pass selected position data using Bundle you can send data to other activity
#Override
public void getposition(int position) {
Intent intent = new Intent(context,DetailsActivity.class);
intent.putExtra("name", bookNameList.get(position));
startActivity(intent);
}
}
}
i used this in my adapter class to get position
public void onClick(View v) {
Intent i = new Intent(context,Bookdetailslayout.class);
i.putExtra("bookname",BookNameList.get(position));
i.putExtra("Image",PicList.get(position));
i.putExtra("author_name",AuthorNameList.get(position));
i.putExtra("publisher_name",PublisherList.get(position));
context.startActivity(i);
}
});
then in the next activity
String imgs=getIntent().getStringExtra("Image");
String Bname=getIntent().getStringExtra("bookname");
title.setText(Bname);
String Author=getIntent().getStringExtra("author_name");
author.setText(Author);
String publisher=getIntent().getStringExtra("publisher_name");
pub.setText(publisher);
Toast.makeText(this,"image "+imgs,Toast.LENGTH_LONG).show();
Picasso.get().load(imgs).into(image);
and it works ..thanks for all the help here
I'm trying to create a code saying "Where the username that is logged in matches the username of a created recipe, only show these database entries in the recyclerview on my MyRecipes.java activity". I'm having trouble working out where to put this potential statement. Looking at my code, where would you put that statement, if or otherwise?
The userLoggedIn and loggedUser is the variable for the currently logged in user.
The thisUser is what I've set as the users pulled from the database when the recyclerview is populating in the recyclerview.java class.
Any help would be greatly appreciated!
RecyclerView.java class
private static String thisUser;
String userLoggedIn = HomeActivity.getUserLogged();
private Context mContext;
private RecipesAdapter mRecipeAdapter;
public void setConfig (RecyclerView recyclerView, Context context, List<Recipes> recipes, List<String> keys){
mContext = context;
mRecipeAdapter = new RecipesAdapter(recipes, keys);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setAdapter(mRecipeAdapter);
}
class RecipeItemView extends RecyclerView.ViewHolder{
private TextView mTitle;
private TextView mIngredients;
private TextView mMethod;
private TextView mUser;
private String key;
public RecipeItemView(ViewGroup parent){
super(LayoutInflater.from(mContext).inflate(R.layout.recipe_list_item, parent,false));
mTitle = (TextView) itemView.findViewById(R.id.tvTitle);
mMethod = (TextView) itemView.findViewById(R.id.tvMethod);
mIngredients = (TextView) itemView.findViewById(R.id.tvIngredients);
mUser = (TextView) itemView.findViewById(R.id.tvUser);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(mContext, RecipeDetails.class);
intent.putExtra("key", key);
intent.putExtra("title", mTitle.getText().toString());
intent.putExtra("ingredients", mIngredients.getText().toString());
intent.putExtra("method", mMethod.getText().toString());
mContext.startActivity(intent);
}
});
}
public void bind(Recipes recipes, String key) {
mTitle.setText(recipes.getTitle());
mIngredients.setText(recipes.getIngredients());
mMethod.setText(recipes.getMethod());
mUser.setText(recipes.getCreatedUser());
thisUser = mUser.getText().toString().trim();
this.key = key;
}
}
public static String getUserLoggedIn(){
return thisUser;
}
class RecipesAdapter extends RecyclerView.Adapter<RecipeItemView> {
private List<Recipes> mRecipeList;
private List<String> mKeys;
public RecipesAdapter(List<Recipes> mRecipeList, List<String> mKeys) {
this.mRecipeList = mRecipeList;
this.mKeys = mKeys;
}
#NonNull
#Override
public RecipeItemView onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new RecipeItemView(parent);
}
#Override
public void onBindViewHolder(#NonNull RecipeItemView holder, int position) {
holder.bind(mRecipeList.get(position), mKeys.get(position));
}
#Override
public int getItemCount() {
return mRecipeList.size();
}
}
}
MyRecipes.java (Where the recycler view populates and shows all the recipes)
String loggedUser = HomeActivity.getUserLogged();
String thisUser = RecyclerViewConfig.getUserLoggedIn();
Button addRecipes;
private RecyclerView mRecyclerView;
private String passedUsername;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_recipes);
passedUsername = getIntent().getStringExtra("loggedUsername1");
mRecyclerView = (RecyclerView) findViewById(R.id.rvRecipes);
new FirebaseDatabaseHelper().readRecipes(new FirebaseDatabaseHelper.DataStatus() {
#Override
public void DataIsLoaded(List<Recipes> recipes, List<String> keys) {
new RecyclerViewConfig().setConfig(mRecyclerView, MyRecipesActivity.this, recipes, keys);
}
#Override
public void DataIsInserted() {
}
#Override
public void DataIsUpdated() {
}
#Override
public void DataIsDeleted() {
}
});
addRecipes = findViewById(R.id.btnAddNewRecipe);
addRecipes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent addrecipe = new Intent(MyRecipesActivity.this, AddRecipes.class);
addrecipe.putExtra("loggedUsername2", passedUsername);
startActivity(addrecipe);
}
});
}
}
If i understand correctly, you need to show the recipes to the user only if he/she is the one who created it? Assuming that, below change in the code will do the trick.
Change your bind() method as follows.
public void bind(Recipes recipes, String key) {
thisUser = mUser.getText().toString().trim();
if(thisUser.equals(recipes.getCreatedUser)) {
mTitle.setText(recipes.getTitle());
mIngredients.setText(recipes.getIngredients());
mMethod.setText(recipes.getMethod());
mUser.setText(recipes.getCreatedUser());
this.key = key;
}
}
Though that is a naive approach, a better approach would be to filter the recipes list with created user when you load data from Firebase with readRecipes() method itself. To do that a query can be used as below(the exact query below might not work for you depending on your DB structure. Change it as needed)
Query query = reference.child("Recipes").orderByChild("userCreated").equalTo(thisUser);