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);
}
}
Related
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();
}
}
I'm new to android studio and firebase and now trying to make a simple chat application.
My code can send the chat data to firebase, but failed to get the data back from firebase so nothing updated in the app.
Note:there no crash, just when I type the chat nothing appear in screen.
Can someone point out where I make it wrong?
Here's my code
MainActivity
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
EditText editText;
RelativeLayout addBtn;
DatabaseReference ref;
FirebaseRecyclerAdapter<ChatMessage,chat_rec> adapter;
FirebaseRecyclerOptions<ChatMessage> options;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView)findViewById(R.id.recyclerView);
editText = (EditText)findViewById(R.id.editText);
addBtn = (RelativeLayout)findViewById(R.id.addBtn);
recyclerView.setHasFixedSize(true);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
ref = FirebaseDatabase.getInstance().getReference();
ref.keepSynced(true);
addBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String message = editText.getText().toString().trim();
if (!message.equals("")) {
ChatMessage chatMessage = new ChatMessage(message, "user");
ref.child("chat").push().setValue(chatMessage);
}
editText.setText("");
}
});
Query text = ref.child("chat").limitToLast(100);
options = new FirebaseRecyclerOptions.Builder<ChatMessage>().setQuery(text, ChatMessage.class).build();
adapter = new FirebaseRecyclerAdapter<ChatMessage, chat_rec>(options) {
#Override
protected void onBindViewHolder(chat_rec viewHolder, int position, ChatMessage model) {
// Bind the Chat object to the ChatHolder
// ...
if (model.getMsgUser().equals("user")) {
viewHolder.rightText.setText(model.getMsgText());
viewHolder.rightText.setVisibility(View.VISIBLE);
viewHolder.leftText.setVisibility(View.GONE);
}
else {
viewHolder.leftText.setText(model.getMsgText());
viewHolder.rightText.setVisibility(View.GONE);
viewHolder.leftText.setVisibility(View.VISIBLE);
}
}
#Override
public chat_rec onCreateViewHolder(ViewGroup parent, int viewType) {
// Create a new instance of the ViewHolder, in this case we are using a custom
// layout called R.layout.message for each item
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.msglist, parent, false);
return new chat_rec(view);
}
};
recyclerView.setAdapter(adapter);
}
}
chat_rec.java
Public class chat_rec extends RecyclerView.ViewHolder {
TextView leftText,rightText;
public chat_rec(View itemView){
super(itemView);
leftText = (TextView)itemView.findViewById(R.id.leftText);
rightText = (TextView)itemView.findViewById(R.id.rightText);
}
}
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'll appreciate if anyone can help me with this.
So what's happening is the Adapter is being declared before the SenderNames Array List is fetched from Firebase Database.So how do I wait for the SenderNames to be fetched first from database and then display them?
Tab 2 code
public class Tab2 extends Fragment {
private static RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private static RecyclerView recyclerView;
private static ArrayList<String> reminderMessages;
protected static ArrayList<String> senderNames;
String receiverUID;
private DatabaseReference mDatabase;
int i =0;
private Button profile;
//Overriden method onCreateView
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Returning the layout file after inflating
//Change R.layout.tab1 in you classes
View v =inflater.inflate(R.layout.tab2, container, false);
final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
reminderMessages = new ArrayList<>();
receiverUID = user.getUid();
mDatabase = FirebaseDatabase.getInstance().getReference();
Query query = mDatabase.child("reminders").orderByChild("receiverUID").equalTo(receiverUID);
//Setting size of recycler view as constant
recyclerView = (RecyclerView) v.findViewById(R.id.my_recycler_view2);
recyclerView.setHasFixedSize(true);
//Setting Linear Layout
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
senderNames = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
//Getting corresponding username of the ReceiverUID
//Getting senderUID
String sUID = ds.child("senderUID").getValue(String.class);
//Getting senders Name
GetSenderName getName = new GetSenderName();
getName.GetSenderssName(sUID);
//Getting message from database
String message = ds.child("reminderMessage").getValue(String.class);
//Adding database to ArrayList
reminderMessages.add(message);
//Getting corresponding username of the ReceiverUID
// Log.d("String names", receiverNames.toString());
}
adapter = new DataAdapter(reminderMessages,senderNames);
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
//Error in Reaching Database
Toast.makeText(getContext(), "Something went Wrong!", Toast.LENGTH_SHORT).show();
}
});
return v;
}
GetSenderName Class
import static com.example.admin.import2.Tab2.senderNames;
public class GetSenderName {private FirebaseAuth auth;
ListView listView;
private DatabaseReference mDatabase;
private String senderName;
public void GetSenderssName(String UID){
mDatabase = FirebaseDatabase.getInstance().getReference().child("users");
//Running a query to find matching UID
Query query = mDatabase.orderByKey().equalTo(UID);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot2) {
// Getting user name with matching UID
for (DataSnapshot users : dataSnapshot2.getChildren()) {
senderName = users.child("username").getValue(String.class);
senderNames.add(senderName);
Log.d("sendername retrieved",senderNames.toString());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
DataAdapter Class
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
private ArrayList<String> reminderMessage;
private ArrayList<String> receiverName;
public DataAdapter(ArrayList<String> reminderMessage,ArrayList<String> receiverName) {
this.reminderMessage = reminderMessage;
this.receiverName = receiverName;
}
#Override
public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup,int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cards_layout, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(DataAdapter.ViewHolder viewHolder, int i) {
viewHolder.reminderText.setText(reminderMessage.get(i));
viewHolder.receiverName.setText(receiverName.get(i));
}
#Override
public int getItemCount() {
return reminderMessage.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView reminderText;
private TextView receiverName;
public ViewHolder(View view) {
super(view);
reminderText = (TextView)view.findViewById(R.id.remindertext);
receiverName = (TextView)view.findViewById(R.id.receiverName);
}
}
}
To avoid problems like populate a list before the databases values are fetched, you should use a FirebaseRecyclerAdapter available in firebaseUI library.
It work in asynchronously so you dont need to do nothing. Just set up the recyclerview, the adapter and the query.
Take a look at the official repository
FirebaseUI
Instead of sending the data in constructor you can create some setter method to set the data and update the list,
Remove the arguments in Adapter constructor
Initialize the ArrayList while declaring as a global variable.
Create a setter method to set the data,
If you do your Adapter will be like this,
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
private ArrayList<String> reminderMessage = new ArrayList<>();
private ArrayList<String> receiverName = new ArrayList<>();
public DataAdapter(ArrayList<String> reminderMessage, ArrayList<String> receiverName) {
this.reminderMessage = reminderMessage;
this.receiverName = receiverName;
}
public void setData(ArrayList<String> reminderMessage, ArrayList<String> receiverName) {
if(reminderMessage == null || receiverName != null) {
return;
}
this.reminderMessage.clear();
this.receiverName.clear();
this.reminderMessage.addAll(reminderMessage);
this.receiverName.addAll(receiverName);
notifyDataSetChanged();
}
#Override
public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cards_layout, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(DataAdapter.ViewHolder viewHolder, int i) {
viewHolder.reminderText.setText(reminderMessage.get(i));
viewHolder.receiverName.setText(receiverName.get(i));
}
#Override
public int getItemCount() {
return reminderMessage.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView reminderText;
private TextView receiverName;
public ViewHolder(View view) {
super(view);
reminderText = (TextView) view.findViewById(R.id.remindertext);
receiverName = (TextView) view.findViewById(R.id.receiverName);
}
}
}
so from your activity you can call like this, adapter.setData(reminderMessages,senderNames); so that you can create the adapter and set in Recycle View before get the data from server.
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.