I have a spinner with locations and I would like to click on the location from the spinner and filter my Firebase data to show all items with that location selected.
I have tried putting the "onItemSelected" code fragment in the onStart area before and after the FirebaseRecyclerOptions and when I open the app and select the location from the spinner nothing new populates. It still shows all the data and all the locations.
public class MainActivity extends AppCompatActivity {
RecyclerView mRecyclerView;
Spinner mLocationSpinner;
DatabaseReference mRef;
FirebaseDatabase mFirebaseDatabase;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recyclerview);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 2));
mFirebaseDatabase = FirebaseDatabase.getInstance();
mRef = (DatabaseReference) mFirebaseDatabase.getReference("Data");
}
#Override
protected void onStart() {
super.onStart();
FirebaseRecyclerOptions<Model> options =
new FirebaseRecyclerOptions.Builder<Model>()
.setQuery(mRef, Model.class)
.build();
FirebaseRecyclerAdapter firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Model, ViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull ViewHolder holder , int position , #NonNull Model model) {
holder.setDetails(getApplicationContext(), model.getBusiness(), model.getImage());
mLocationSpinner = (SearchableSpinner) findViewById(R.id.locationSpinner);
ArrayAdapter<CharSequence> spinAdapter = ArrayAdapter.createFromResource(MainActivity.this,
R.array.location_arrays, android.R.layout.simple_spinner_item);
spinAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mLocationSpinner.setAdapter(spinAdapter);
mLocationSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent , View view , int position , long id) {
String locationSpinner = parent.getItemAtPosition(position).toString();
Query querySpinner = mRef.orderByChild("location").equalTo(String.valueOf(mLocationSpinner));
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent , int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.row, parent, false);
return new ViewHolder(view);
}
};
firebaseRecyclerAdapter.startListening();
mRecyclerView.setAdapter(firebaseRecyclerAdapter);
}
Related
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){
When my app start up the recyclerview loads up. But when I change my activity, like, when i go to ProfileActivity from DashboardActivity and Come back to DashboardActivity the recyclerview vanishes. I don't get the problem.
This part is in onCreate method
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setAdapter(adapter);
adapter.startListening();
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(layoutManager);
This is the onStart method
#Override
protected void onStart() {
super.onStart();
Query query = firebaseFirestore.collection("requests")
.orderBy("creationTime", Query.Direction.DESCENDING);
FirestoreRecyclerOptions<Request> options = new FirestoreRecyclerOptions.Builder<Request>()
.setQuery(query, Request.class)
.build();
FirestoreRecyclerAdapter<Request, RequestViewHolder> adapter =
new FirestoreRecyclerAdapter<Request, RequestViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull RequestViewHolder holder, int i, #NonNull Request request) {
holder.requestUserNameTV.setText(request.getUser().getFullName());
holder.requestCreationTimeTV.setText(request.getCreationTime());
holder.requestedBloodGroupTV.setText(request.getBloodGroup());
holder.requestLocationTV.setText(request.getLocation());
holder.requestMessageTV.setText(request.getMessage());
}
#NonNull
#Override
public RequestViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview, parent, false);
return new RequestViewHolder(v);
}
};
recyclerView.setAdapter(adapter);
adapter.startListening();
}
This is the ViewHolder
public class RequestViewHolder extends RecyclerView.ViewHolder {
public TextView requestUserNameTV, requestCreationTimeTV, requestedBloodGroupTV;
public TextView requestLocationTV, requestMessageTV;
public LinearLayout ll;
public RequestViewHolder(#NonNull View itemView) {
super(itemView);
ll = itemView.findViewById(R.id.ll);
requestUserNameTV = itemView.findViewById(R.id.requestUserNameTV);
requestCreationTimeTV = itemView.findViewById(R.id.requestCreationTimeTV);
requestedBloodGroupTV = itemView.findViewById(R.id.requestedBloodGroupTV);
requestLocationTV = itemView.findViewById(R.id.requestedLocationTV);
requestMessageTV = itemView.findViewById(R.id.requestMessageTV);
}
}
Move your code from OnStart to OnCreate. it should solve your problem
Now I'm doing it this way. and it works.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
setUpRecyclerView();
}
private void setUpRecyclerView() {
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
firebaseFirestore = FirebaseFirestore.getInstance();
Query query = firebaseFirestore.collection("requests")
.orderBy("creationTime", Query.Direction.DESCENDING);
FirestoreRecyclerOptions<Request> options = new FirestoreRecyclerOptions.Builder<Request>()
.setQuery(query, Request.class)
.build();
FirestoreRecyclerAdapter<Request, RequestViewHolder> adapter =
new FirestoreRecyclerAdapter<Request, RequestViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull RequestViewHolder holder, int i, #NonNull Request request) {
holder.requestUserNameTV.setText(request.getUser().getFullName());
holder.requestCreationTimeTV.setText(request.getCreationTime());
holder.requestedBloodGroupTV.setText(request.getBloodGroup());
holder.requestLocationTV.setText(request.getLocation());
holder.requestMessageTV.setText(request.getMessage());
}
#NonNull
#Override
public RequestViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview, parent, false);
RequestViewHolder requestViewHolder = new RequestViewHolder(v);
return requestViewHolder;
}
};
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
adapter.startListening();
}
I've used firebase Recycler Adapter to get data. But always getting error,
Attempt to invoke virtual method 'void
androidx.recyclerview.widget.RecyclerView.setAdapter(androidx.recyclerview.widget.RecyclerView$Adapter)'
on a null object reference
My fragment is
public class MyBooksFragment extends BaseFragment {
private ShimmerFrameLayout mShimmerViewContainer;
private RecyclerView recyclerView ;
private FirebaseRecyclerAdapter adapter;
private FirebaseUser user= FirebaseAuth.getInstance().getCurrentUser();
#Override
public BaseFragment provideFragment() {
return new MyBooksFragment();
}
#Override
public View provideFragmentView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my_books,parent,false);
mShimmerViewContainer=view.findViewById(R.id.mybook_shimmer_view_container);
RecyclerView recyclerView = view.findViewById(R.id.recycler_view_books);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
fetchBooks(1);
FloatingActionButton fab = view.findViewById(R.id.addBookFab_);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), BookAdder.class);
startActivity(intent);
}
});
return view;
}
private FirebaseRecyclerOptions<Book> queryBuilderParser(){
Query bookQuery= FirebaseDatabase
.getInstance()
.getReference()
.child("Books")
.orderByChild("ownerID")
.equalTo(user.getUid());
FirebaseRecyclerOptions<Book> options =
new FirebaseRecyclerOptions.Builder<Book>()
.setQuery(bookQuery,Book.class)
.build();
return options;
}
protected void fetchBooks(int type)
{
Log.e("profile",type+" ");
FirebaseRecyclerOptions<Book> options;
Query bookQuery= FirebaseDatabase
.getInstance()
.getReference()
.child("Books")
.orderByChild("ownerID")
.equalTo(user.getUid());
options = new FirebaseRecyclerOptions.Builder<Book>()
.setQuery(bookQuery,Book.class)
.build();
Log.e("profile","inside fetchReviw "+options.getSnapshots());
adapter= new FirebaseRecyclerAdapter<Book, BookViewHolder>(options) {
#NonNull
#Override
public BookViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.book_row_item, parent, false);
return new BookViewHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull BookViewHolder bookViewHolder, int i, #NonNull Book book) {
bookViewHolder.book_name.setText(book.getBookName());
bookViewHolder.book_author.setText(book.getAuthors());
bookViewHolder.book_category.setText(book.getCategory());
bookViewHolder.book_rating.setText(book.getRating()+"");
Glide.with(getActivity()).load(book.getThumbnail()).into(bookViewHolder.img_thumbnail);
}
#Override
public void onDataChanged() {
if(getItemCount()>0 && mShimmerViewContainer!=null){
mShimmerViewContainer.stopShimmerAnimation();
mShimmerViewContainer.setVisibility(View.GONE);
}
}
#Override
public void onError(DatabaseError e) {
// Called when there is an error getting data. You may want to update
// your UI to display an error message to the user.
// ...
Log.e("profile","database error");
}
};
recyclerView.setAdapter(adapter);
}
}
Here, I've extended a base fragment which extends Fragment.
You haven't put the right arguments into the adapter. The adapter takes 4 arguments in:
Object class
List item layout resource
Viewholder Class
Query/firebase reference
Here is how it should look, also the adapter does a lot of the hard word so you only need to use the populateViewHolder function:
FirebaseRecyclerViewAdapter<Object, ObjectViewHolder> adapter = new FirebaseRecyclerViewAdapter<Object, ObjectViewHolder>
(Object.class, android.R.layout.*list_item_layout*, ObjectViewHolder.class, objectQuery) {
public void populateViewHolder(ObjectViewHolder ObjectViewHolder, Object Object) {
//in your case the following lines:
bookViewHolder.book_name.setText(book.getBookName());
bookViewHolder.book_author.setText(book.getAuthors());
bookViewHolder.book_category.setText(book.getCategory());
bookViewHolder.book_rating.setText(book.getRating()+"");
Glide.with(getActivity()).load(book.getThumbnail()).into(bookViewHolder.img_thumbnail);
}
};
recycler.setAdapter(mAdapter);
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);
}
}
I have a fragment called HomeFragment inside an activity called MainActivity that using RecyclerView to load the data from Firebase. And when I clicked the RecyclerView, it will open a new activity called ItemActivity.
The problem is sometimes the RecyclerView does not load anything when it opened the new activity.
For example, I clicked the RecyclerView in the HomeFragment, the new ItemActivity will start but without any RecyclerView, and after I closed it and reopen it again, the RecyclerView is showing. This happened on a random occasion, sometimes it loads and sometimes it does not load the RecyclerView.
And whenever I put adapter.stopListening(), the RecyclerView never show up in the ItemActivity.
HomeFragment
public class HomeFragment extends Fragment {
private OnFragmentInteractionListener mListener;
FirebaseDatabase database;
DatabaseReference category;
FirebaseRecyclerAdapter adapter;
TextView txtUsername;
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
public HomeFragment() {
// Required empty public constructor
}
public static HomeFragment newInstance(String param1, String param2) {
HomeFragment fragment = new HomeFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
database = FirebaseDatabase.getInstance();
category = database.getReference("Category");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_home, container,false);
// set name for user
String username = Common.currentUser.getEmail();
StringTokenizer tokens = new StringTokenizer(username, "#");
String first = tokens.nextToken();// this will contain string before #
// set name for user
txtUsername = (TextView) view.findViewById(R.id.textUsername);
txtUsername.setText(first);
// load category
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerViewCategory);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
loadMenu();
return view;
}
private void loadMenu(){
Query query = FirebaseDatabase
.getInstance()
.getReference()
.child("Category");
FirebaseRecyclerOptions<Category> options =
new FirebaseRecyclerOptions.Builder<Category>()
.setQuery(query, Category.class)
.build();
adapter = new FirebaseRecyclerAdapter<Category, CategoryViewHolder>(options) {
#Override
public CategoryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(getActivity())
.inflate(R.layout.category_item, parent, false);
return new CategoryViewHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull CategoryViewHolder holder, int position, #NonNull Category model) {
holder.txtMenuName.setText(model.getName());
Picasso.with(getActivity()).load(model.getImage())
.into(holder.imageView);
final Category clickItem = model;
holder.setItemClickListener(new ItemClickListener() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
// get category id and send to new activity
Intent intent = new Intent(getActivity(), ItemActivity.class);
// get category id to filter
intent.putExtra("CategoryId",adapter.getRef(position).getKey());
startActivity(intent);
}
});
}
};
recyclerView.setAdapter(adapter);
}
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onStop() {
super.onStop();
//adapter.stopListening();
}
#Override
public void onStart() {
super.onStart();
adapter.startListening();
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
//Toast.makeText(context, "Home Fragment Attached", Toast.LENGTH_SHORT).show();
}
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri);
}
ItemActivity
public class ItemActivity extends AppCompatActivity {
ImageView imageView;
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
FirebaseDatabase database;
DatabaseReference itemList;
String categoryId;
public FirebaseRecyclerAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
// Firebase
database= FirebaseDatabase.getInstance();
itemList = database.getReference("Item");
recyclerView = (RecyclerView) findViewById(R.id.recyclerViewItem);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
// get intent
if (getIntent() != null) {
categoryId = getIntent().getStringExtra("CategoryId");
}
if(!categoryId.isEmpty() && categoryId != null) {
loadListItem(categoryId);
}
}
private void loadListItem(String categoryId) {
Query query = itemList.orderByChild("CategoryId").equalTo(categoryId);
FirebaseRecyclerOptions<Item> options =
new FirebaseRecyclerOptions.Builder<Item>()
.setQuery(query, Item.class)
.build();
adapter = new FirebaseRecyclerAdapter<Item, ItemViewHolder>(options) {
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.product_item, parent, false);
return new ItemViewHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull ItemViewHolder holder, int position, #NonNull Item model) {
holder.itemTitle.setText(model.getName());
holder.itemUsername.setText(model.getUsername());
holder.itemPrice.setText(model.getPrice());
holder.itemDescription.setText(model.getDescription());
holder.itemPhone.setText(model.getPhone());
holder.itemDate.setText(model.getDate());
holder.itemQuality.setText(model.getQuality());
Picasso.with(getBaseContext()).load(model.getPicture())
.into(holder.itemImage);
final Item clickItem = model;
holder.setItemClickListener(new ItemClickListener() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
//
}
});
}
};
adapter.startListening();
recyclerView.setAdapter(adapter);
Toast.makeText(this, "" + categoryId, Toast.LENGTH_SHORT).show();
}
#Override
public void onStart() {
super.onStart();
//adapter.startListening();
}
#Override
public void onStop() {
super.onStop();
//adapter.stopListening();
}
I found the problem.
Just remove recyclerView.setHasFixedSize(true);