As mentioned in the title, my recyclerview does not work. No idea why, because I do not get any errors or anything in the logcat or while building the app. Is there a way I could debug this or could you point out the mistake that I did?
I've implemented another recyclerview with the adapter, but I used a simple adapter. I tried using the firebaseUI in this case, and it seems that the adapter somehow cannot retrieve the data from the firebase firestore.
https://imgur.com/a/JSLXuou The screenshot of my database structure.
My adapter:
public class ManageAdapter extends FirestoreRecyclerAdapter<Manage, ManageAdapter.ManageHolder> {
public ManageAdapter(#NonNull FirestoreRecyclerOptions<Manage> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull ManageHolder holder, int position, #NonNull Manage model) {
holder.textviewName.setText(model.getName());
holder.textviewGrade.setText(model.getGrade());
//holder.textviewAge.setText(String.valueOf(model.getAge()));
}
#NonNull
#Override
public ManageHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.manage_item,
parent,false);
return new ManageHolder(v);
}
class ManageHolder extends RecyclerView.ViewHolder{
TextView textviewName;
TextView textviewAge;
TextView textviewGrade;
public ManageHolder(#NonNull View itemView) {
super(itemView);
textviewAge = itemView.findViewById(R.id.manage_item_title_age);
textviewGrade = itemView.findViewById(R.id.manage_item_grade);
textviewName = itemView.findViewById(R.id.manage_item_name);
}
}
}
Main class:
private FirebaseFirestore firebaseFirestore;
private Toolbar mToolbar;
private Button delete_event;
private RecyclerView participants;
private TextView manage_events_title;
private TextView participans_text;
private ManageAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_events);
final String ID = getIntent().getExtras().getString("ID");
firebaseFirestore = FirebaseFirestore.getInstance();
delete_event = (Button) findViewById(R.id.delete_event);
manage_events_title = (TextView) findViewById(R.id.manage_events_title);
participans_text = (TextView) findViewById(R.id.participants_text);
participants = (RecyclerView) findViewById(R.id.recyclerview_manage);
setUpRecyclerView();
}
private void setUpRecyclerView(){
final String ID = getIntent().getExtras().getString("ID");
Query query = firebaseFirestore.collection("Events").document(ID).collection("Users");
FirestoreRecyclerOptions<Manage> options = new FirestoreRecyclerOptions.Builder<Manage>()
.setQuery(query, Manage.class).build();
adapter = new ManageAdapter(options);
participants.setHasFixedSize(true);
participants.setLayoutManager(new LinearLayoutManager(this));
participants.setAdapter(adapter);
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
}
Related
I started learning Firebase Firestore and this is my very first learning project.
In a tutorial that I'm following, the tutor uses FirestoreRecyclerAdapter, but in my code it's showing an error that I am using FirestoreRecyclerAdapter instead of Adapter.
Error:
at--------- recyclerView.setAdapter(adapter) commented errer ----------------------'setAdapter(androidx.recyclerview.widget.RecyclerView.Adapter)' in 'androidx.recyclerview.widget.RecyclerView' cannot be applied to '(com.firebase.ui.firestore.FirestoreRecyclerAdapter<com.dharmik953.mynotes_firebase.firebaseModel,com.dharmik953.mynotes_firebase.HomePage.NoteViewHolder>)'
I don't know where the problem is, please help me to find it.
FloatingActionButton addNotes;
FirebaseAuth mAuth;
RecyclerView recyclerView;
StaggeredGridLayoutManager layoutManager;
FirebaseFirestore firestore;
FirestoreRecyclerAdapter<firebaseModel,NoteViewHolder> adapter;
FirebaseUser user;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_page);
addNotes = findViewById(R.id.add_button);
mAuth = FirebaseAuth.getInstance();
firestore = FirebaseFirestore.getInstance();
user = FirebaseAuth.getInstance().getCurrentUser();
Objects.requireNonNull(getSupportActionBar()).setTitle("Notes");
addNotes.setOnClickListener(v -> startActivity(new Intent(HomePage.this,addNotes.class)));
Query query = firestore.collection("notes").document(user.getUid()).collection("myNotes").orderBy("title",Query.Direction.ASCENDING);
FirestoreRecyclerOptions<firebaseModel> userNotes = new FirestoreRecyclerOptions.Builder<firebaseModel>().setQuery(query,firebaseModel.class).build();
adapter = new FirestoreRecyclerAdapter<firebaseModel, NoteViewHolder>(userNotes) {
#Override
protected void onBindViewHolder(#android.support.annotation.NonNull #NonNull NoteViewHolder holder, int position, #android.support.annotation.NonNull #NonNull firebaseModel model) {
holder.title.setText(firebaseModel.getTitle());
holder.content.setText(firebaseModel.getContent());
}
#android.support.annotation.NonNull
#NonNull
#Override
public NoteViewHolder onCreateViewHolder(#android.support.annotation.NonNull #NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.notes_layout,parent,false);
return new NoteViewHolder(view);
}
};
recyclerView = findViewById(R.id.recyclerview);
recyclerView.setHasFixedSize(true);
layoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter); //here showing error --> 'setAdapter(androidx.recyclerview.widget.RecyclerView.Adapter)' in 'androidx.recyclerview.widget.RecyclerView' cannot be applied to '(com.firebase.ui.firestore.FirestoreRecyclerAdapter<com.dharmik953.mynotes_firebase.firebaseModel,com.dharmik953.mynotes_firebase.HomePage.NoteViewHolder>)'
}
public class NoteViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder{
private TextView title;
private TextView content;
LinearLayout layout;
public NoteViewHolder(#NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.note_title);
content = itemView.findViewById(R.id.note_description);
layout = itemView.findViewById(R.id.Note);
}
}
My recyclerview always reset to first position after new data is inserted to firebase. In my TestAdapter class, I have an onClickListener which increments like on a post when clicked. Whenever I click on this "like" button, view is reset to first position. I believe this issue is related to setAdapter() being called on data changed. Please help!
MainActivity fetches "post" data from Firebase and populates it in TestAdapter class.
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private TestAdapter testAdapter;
private ArrayList<Post> postList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
fetchPostFromDB();
}
private void fetchPostFromDB() {
DatabaseReference databaseRef = FirebaseDatabase.getInstance().getReference("Post");
databaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
postList = new ArrayList<>();
for (DataSnapshot snap : snapshot.getChildren()) {
String post = snap.child("post").getValue().toString();
Post post = new Post(post);
postList.add(post);
}
testAdapter = new TestAdapter(getApplicationContext(), postList);
recyclerView.setAdapter(testAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
TestAdapter binds the data (postList) and has an onClickListener.
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.TestHolder> {
private List<Post> postList;
private Context context;
private DatabaseReference databaseReference;
public TestAdapter(Context ct, ArrayList<Post> postList) {
context = ct;
this.postList = postList;
}
#NonNull
#Override
public TestHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.post_item, parent, false);
final TestHolder holder = new TestHolder(view);
holder.ibLike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String postID = postList.get(holder.getAdapterPosition()).getPostID();
databaseReference = FirebaseDatabase.getInstance().getReference("Posts").child(postID).child("likes");
int incrementLike = postList.get(holder.getAdapterPosition()).getLikes() + 1;
databaseReference.setValue(incrementLike);
}
});
return holder;
}
#Override
public void onBindViewHolder(#NonNull final TestHolder holder, final int position) {
holder.tvPost.setText(postList.get(position).getPost());
holder.tvVotes.setText(Integer.toString(postList.get(position).getLikes()));
}
#Override
public int getItemCount() {
return postList.size();
}
public static class TestHolder extends RecyclerView.ViewHolder {
TextView tvPost, tvLikes;
ImageButton ibLike;
public TestHolder(#NonNull View itemView) {
super(itemView);
tvPost = itemView.findViewById(R.id.tvPost);
tvLikes = itemView.findViewById(R.id.tvLikes);
ibLike = itemView.findViewById(R.id.ibLike);
}
}
Here need to initialize your adapter class from main activity. and then when data received just call adapter.notifiyDatasetChanged like:
onCreate():
postList = new ArrayList<>();
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
testAdapter = new TestAdapter(getApplicationContext(), postList);
recyclerView.setAdapter(testAdapter);
and from your fetchPostFromDB delete adapter initialization insted of this just put this line testAdapter.notifiyDataSetChanged()
And when click on text button you can update/handle like this:
holder.ibLike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String postID = postList.get(holder.getAdapterPosition()).getPostID();
databaseReference = FirebaseDatabase.getInstance().getReference("Posts").child(postID).child("likes");
int incrementLike = postList.get(holder.getAdapterPosition()).getLikes() + 1;
postList.get(holder.getAdapterPosition()).setLikes(incrementLike);
databaseReference.setValue(incrementLike);
notifyDataSetChanged();
}
});
the error message is : incompatible types: FirestoreRecyclerOptions cannot be converted to FirebaseRecyclerOptions ----
and the code is as follows.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_agencies);
firebaseFirestore= FirebaseFirestore.getInstance();
//views definition
agencyFeed = (RecyclerView)findViewById(R.id.agencyRecyclerView);
//------Requirements for retrieving data and storing it to recycler view---
//Query ----- for retrieving data from firestore
Query query = firebaseFirestore.collection("Agencies");
// recyclerOptions
FirestoreRecyclerOptions<AgencyModel> options = new FirestoreRecyclerOptions.Builder<AgencyModel>()
.setQuery(query,AgencyModel.class)
.build();
adapter = new FirebaseRecyclerAdapter<AgencyModel, AgencyViewHolder>(options){
#NonNull
#Override
public AgencyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.agency_cards,parent,false);
return new AgencyViewHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull AgencyViewHolder holder, int position, #NonNull AgencyModel model) {
holder.name.setText(model.getName());
holder.location.setText(model.getLocation());
}
};
agencyFeed.hasFixedSize();
agencyFeed.setLayoutManager(new GridLayoutManager(this,2));
agencyFeed.setAdapter(adapter);
}
//viewholder class
public class AgencyViewHolder extends RecyclerView.ViewHolder {
private TextView name, location;
public AgencyViewHolder(#NonNull View itemView) {
super(itemView);
name= itemView.findViewById(R.id.agency_name); //name of agency
location= itemView.findViewById(R.id.locationTextView);
}
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
}
You are using Firestore according to your query, therefore you have to use FirestoreRecyclerAdapter and not FirebaseRecyclerAdapter. Therefore change:
adapter = new FirebaseRecyclerAdapter<AgencyModel, AgencyViewHolder>(options){
into this:
adapter = new FirestoreRecyclerAdapter<AgencyModel, AgencyViewHolder>(options){
This question already has answers here:
FirebaseRecyclerAdapter unable to populate result [duplicate]
(1 answer)
FirebaseListAdapter not pushing individual items for chat app - Firebase-Ui 3.1
(2 answers)
Closed 5 years ago.
I am following a youtube video in which I was trying to retrieve data using FirebaseUI but I am not able to show any data in the recyclerview.
Here is the code
public class MemeFragment extends Fragment {
RecyclerView recyclerView;
FirebaseDatabase firebaseDatabase;
DatabaseReference myref;
FirebaseRecyclerAdapter<Datafileinfo, ShowDataViewHolder> firebaseRecyclerAdapter;
FirebaseRecyclerOptions<Datafileinfo> options;
public MemeFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_meme, container, false);
firebaseDatabase = FirebaseDatabase.getInstance();
myref = FirebaseDatabase.getInstance().getReference("memes");
recyclerView = (RecyclerView) view.findViewById(R.id.recyc);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
options = new FirebaseRecyclerOptions.Builder<Datafileinfo>()
.setQuery(myref, Datafileinfo.class)
.build();
return view;
}
#Override
public void onStart() {
super.onStart();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Datafileinfo, ShowDataViewHolder>
(options) {
#Override
protected void onBindViewHolder(#NonNull ShowDataViewHolder holder, int position, #NonNull Datafileinfo model) {
holder.ImageTitle(model.getTitle());
holder.ImageUrl(model.getImage());
}
#Override
public ShowDataViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.custo, parent, false);
return new ShowDataViewHolder(view);
}
};
recyclerView.setAdapter(firebaseRecyclerAdapter);
}
public static class ShowDataViewHolder extends RecyclerView.ViewHolder {
private ImageView imageView;
private TextView textView;
public ShowDataViewHolder(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.imageView);
textView = (TextView) itemView.findViewById(R.id.textView);
}
private void ImageTitle(String title) {
textView.setText(title);
}
private void ImageUrl(String url) {
Glide.with(itemView.getContext()).
load(url).
into(imageView);
}
}
}
and datafileinfo is the getter and setter class I have also taken the internet permission.Note I am able to get the single value from firebase but for multiple values, I am facing a problem this is the database.
where I am doing wrong any idea??
Note I have followed and gone through all the tutorials and similar post.
Create a separate Class for your ViewHolder
public class ShowDataViewHolder extends RecyclerView.ViewHolder{
private ImageView imageView;
private TextView textView;
public ShowDataViewHolder (View itemView) {
super(itemView);
imageView = (ImageView)itemView.findViewById(R.id.imageView);
textView = (TextView) itemView.findViewById(R.id.textView);
}
}
In your MenuFragment add
DatabaseReference mDatabaseMemes= //your reference to memes node
FirebaseRecyclerAdapter<yourModel, ShowDataViewHolder> adapter= new FirebaseRecyclerAdapter<yourModel, ShowDataViewHolder>(yourModel.class, R.layout.yourLayout,
ShowDataViewHolder.class,mDatabaseMemes) {
#Override
protected void populateViewHolder(ShowDataViewHolder viewHolder, yourModel model, int position) {
viewHolder.textView.setText(model.getTitle());
Glide.with(context)
.load(model.getImage())
.fitCenter()
.into(viewHolder.imageView);
}
};
recyclerView.setAdapter(adapter);
}
MAKE SURE your model class has String title and image same as your child names under memes node.
I want to obtain determined value from the Realtime DB using FirebaseRecyclerAdapter. This is my class:
public class ProductAvtivity extends AppCompatActivity {
private final String TAG = "ProductActivity";
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private FirebaseDatabase database;
private DatabaseReference mProductReference;
private Query mMachineReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product_avtivity);
database = FirebaseDatabase.getInstance();
mProductReference = database.getReference().child("products");
String idmachine = getIntent().getStringExtra("idmachine");
mMachineReference = database.getReference().child("machines").child("_id").equalTo(idmachine);
Log.d(TAG + "idmachine",idmachine);
mRecyclerView = (RecyclerView) findViewById(R.id.product_recyclerview);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
FirebaseRecyclerAdapter<Product,ProductViewHolder> adapter =
new FirebaseRecyclerAdapter<Product, ProductViewHolder>(Product.class,R.layout.view_product,ProductViewHolder.class,mProductReference) {
#Override
protected void populateViewHolder(ProductViewHolder viewHolder, Product model, int position) {
viewHolder.productName.setText(model.name);
}
};
mRecyclerView.setAdapter(adapter);
}
public static class ProductViewHolder extends RecyclerView.ViewHolder{
TextView productName;
public ProductViewHolder(View itemView) {
super(itemView);
productName = (TextView) itemView.findViewById(R.id.product_name);
}
}
}
I tried it with this solution but it's not working because the activity crashes:
public class ProductAvtivity extends AppCompatActivity {
private final String TAG = "ProductActivity";
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private FirebaseDatabase database;
private DatabaseReference mProductReference;
private Query mMachineReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product_avtivity);
database = FirebaseDatabase.getInstance();
mProductReference = database.getReference().child("products");
String idmachine = getIntent().getStringExtra("idmachine");
mMachineReference = database.getReference().child("machines").child("_id").equalTo(idmachine);
Log.d(TAG + "idmachine",idmachine);
mRecyclerView = (RecyclerView) findViewById(R.id.product_recyclerview);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
FirebaseRecyclerAdapter<Product,ProductViewHolder> adapter =
new FirebaseRecyclerAdapter<Product, ProductViewHolder>(Product.class,R.layout.view_product,ProductViewHolder.class,mProductReference) {
#Override
protected void populateViewHolder(final ProductViewHolder viewHolder, final Product model, int position) {
mMachineReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Machine machine = dataSnapshot.getValue(Machine.class);
for (Integer i : machine.id_prod){
if (model._id == i){
viewHolder.productName.setText(model.name);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
};
mRecyclerView.setAdapter(adapter);
}
public static class ProductViewHolder extends RecyclerView.ViewHolder{
TextView productName;
public ProductViewHolder(View itemView) {
super(itemView);
productName = (TextView) itemView.findViewById(R.id.product_name);
}
}
}
I have a list of product for all machine IDs and then I pass this from another activity where the user selects the machine. By this selection, I have to list in the recyclerview the product connected to it.