i am trying to fetch data from firebase Realtime database and showing the data in recycler view but it shows an error
recyclerView = findViewById(R.id.RecyclerView);
recyclerView.setHasFixedSize(true);
databaseReference = firebaseDatabase.getInstance().getReference().child("Collection");
options = new FirebaseRecyclerOptions.Builder<CategoryItem>().setQuery(databaseReference,CategoryItem.class).build();
adapter = new FirebaseRecyclerAdapter<CategoryItem, CtegoryViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull CtegoryViewHolder holder, int position, #NonNull CategoryItem model) {
Picasso.get().load(model.getImageLink()).into(holder.i1, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError(Exception e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
holder.t1.setText(model.getName());
}
#NonNull
#Override
public CtegoryViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_view_layout,viewGroup,false);
return new CtegoryViewHolder(view);
}
};
androidx.recyclerview.widget.GridLayoutManager gridLayoutManager = new GridLayoutManager(this,1);
recyclerView.setLayoutManager(gridLayoutManager);
adapter.startListening();
recyclerView.setAdapter(adapter);
Related
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();
}
Im attempting a FireBase Horizontal RecyclerView (like an Netflix clone).
I have looked at Git and Android Arsenal to find programing similar, but had been unsuccessful finding anything with a firebase backend. I had played with the adapter and the database. I have work on this for a couple days without finding a solution.
public class RestaurantList extends AppCompatActivity {
RecyclerView recyclerView1;
RecyclerView recyclerView2;
FirebaseRecyclerOptions<Restaurant> options = new FirebaseRecyclerOptions.Builder<Restaurant>()
.setQuery(FirebaseDatabase.getInstance()
.getReference()
.child("Restaurants1")
,Restaurant.class)
.build();
FirebaseRecyclerAdapter<Restaurant, RestaurantViewHolder> adapter = new FirebaseRecyclerAdapter<Restaurant, RestaurantViewHolder>(options) {
#NonNull
#Override
public RestaurantViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.restaurant_item, parent, false);
return new RestaurantViewHolder(itemView);
}
#Override
protected void onBindViewHolder(#NonNull RestaurantViewHolder viewHolder, int position, #NonNull Restaurant model) {
viewHolder.txt_restaurant_name.setText(model.getName());
Picasso.get().load(model.getImage())
.into(viewHolder.img_restaurant);
final Restaurant clickItem = model;
viewHolder.setItemClickListener(new ItemClickListener() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
Intent foodList = new Intent(RestaurantList.this, Home.class);
Common.restaurantSelected=adapter.getRef(position).getKey();
startActivity(foodList);
}
});
}
};
FirebaseRecyclerOptions<Restaurant> options2 = new FirebaseRecyclerOptions.Builder<Restaurant>()
.setQuery(FirebaseDatabase.getInstance()
.getReference()
.child("Restaurants2")
,Restaurant.class)
.build();
FirebaseRecyclerAdapter<Restaurant, RestaurantViewHolder> adapter2= new FirebaseRecyclerAdapter<Restaurant, RestaurantViewHolder>(options2) {
#NonNull
#Override
public RestaurantViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.restaurant_item, parent, false);
return new RestaurantViewHolder(itemView);
}
#Override
protected void onBindViewHolder(#NonNull RestaurantViewHolder viewHolder, int position, #NonNull Restaurant model) {
viewHolder.txt_restaurant_name.setText(model.getName());
Picasso.get().load(model.getImage())
.into(viewHolder.img_restaurant);
final Restaurant clickItem = model;
viewHolder.setItemClickListener(new ItemClickListener() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
Intent foodList = new Intent(RestaurantList.this, Home.class);
Common.restaurantSelected=adapter2.getRef(position).getKey();
startActivity(foodList);
}
});
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_restaurant_list);
RelativeLayout relativeLayout = findViewById(R.id.root2_layout);
AnimationDrawable animationDrawable = (AnimationDrawable)relativeLayout.getBackground();
animationDrawable.setEnterFadeDuration(5);
animationDrawable.setExitFadeDuration(1000);
animationDrawable.start();
LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);
LinearLayoutManager layoutManager2 = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);
recyclerView1 = (RecyclerView) findViewById(R.id.recycler_restaurant);
recyclerView1.setLayoutManager(layoutManager);
recyclerView2 = (RecyclerView) findViewById(R.id.recycler_restaurant2);
recyclerView1.setLayoutManager(layoutManager2);
loadAsianFood();
loadSteakHouse();
}
private void loadSteakHouse() {
adapter.startListening();
recyclerView1.setAdapter(adapter);
recyclerView1.getAdapter().notifyDataSetChanged();
recyclerView1.scheduleLayoutAnimation();
}
private void loadAsianFood() {
adapter2.startListening(); // Did you mean adapter2.startListening()?
recyclerView2.setAdapter(adapter2);
recyclerView2.getAdapter().notifyDataSetChanged();
recyclerView2.scheduleLayoutAnimation();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
adapter2.stopListening();;
}
#Override
protected void onResume() {
super.onResume();
if (adapter != null)
adapter.startListening();
adapter2.startListening();
}
}
It only runs the first category (Restaurant1) only.
A few problems I noticed, though I don't know if they'll solve your actual issue.
1 - You are calling startListening on the first adapter when it should be the second:
private void loadAsianFood() {
adapter.startListening(); // Did you mean adapter2.startListening()?
recyclerView2.setAdapter(adapter2);
recyclerView2.getAdapter().notifyDataSetChanged();
recyclerView2.scheduleLayoutAnimation();
}
2 - You are only stopping the first adapter, not the second.
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
3 - You are only resuming the first adapter, not the second:
#Override
protected void onResume() {
super.onResume();
if (adapter != null)
adapter.startListening();
}
RecyclerView recyclerView1;
RecyclerView recyclerView2;
FirebaseRecyclerOptions<Restaurant> options = new FirebaseRecyclerOptions.Builder<Restaurant>()
.setQuery(FirebaseDatabase.getInstance()
.getReference("RestaurantCategory")
.child("01").child("SteakHouse")
,Restaurant.class)
.build();
FirebaseRecyclerAdapter<Restaurant, RestaurantViewHolder> adapter = new FirebaseRecyclerAdapter<Restaurant, RestaurantViewHolder>(options) {
#NonNull
#Override
public RestaurantViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.restaurant_item, parent, false);
return new RestaurantViewHolder(itemView);
}
#Override
protected void onBindViewHolder(#NonNull RestaurantViewHolder viewHolder, int position, #NonNull Restaurant model) {
viewHolder.txt_restaurant_name.setText(model.getName());
Picasso.get().load(model.getImage())
.into(viewHolder.img_restaurant);
final Restaurant clickItem = model;
viewHolder.setItemClickListener(new ItemClickListener() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
Intent foodList = new Intent(RestaurantList.this, Home.class);
Common.restaurantSelected=adapter.getRef(position).getKey();
startActivity(foodList);
}
});
}
};
FirebaseRecyclerOptions<Restaurant> options2 = new FirebaseRecyclerOptions.Builder<Restaurant>()
.setQuery(FirebaseDatabase.getInstance()
.getReference("RestaurantCategory")
.child("02").child("AsianFood")
,Restaurant.class)
.build();
FirebaseRecyclerAdapter<Restaurant, RestaurantViewHolder> adapter2= new FirebaseRecyclerAdapter<Restaurant, RestaurantViewHolder>(options2) {
#NonNull
#Override
public RestaurantViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.restaurant_item, parent, false);
return new RestaurantViewHolder(itemView);
}
#Override
protected void onBindViewHolder(#NonNull RestaurantViewHolder viewHolder, int position, #NonNull Restaurant model) {
viewHolder.txt_restaurant_name.setText(model.getName());
Picasso.get().load(model.getImage())
.into(viewHolder.img_restaurant);
final Restaurant clickItem = model;
viewHolder.setItemClickListener(new ItemClickListener() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
Intent foodList = new Intent(RestaurantList.this, Home.class);
Common.restaurantSelected=adapter2.getRef(position).getKey();
startActivity(foodList);
}
});
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_restaurant_list);
RelativeLayout relativeLayout = findViewById(R.id.root2_layout);
AnimationDrawable animationDrawable = (AnimationDrawable)relativeLayout.getBackground();
animationDrawable.setEnterFadeDuration(5);
animationDrawable.setExitFadeDuration(1000);
animationDrawable.start();
LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);
LinearLayoutManager layoutManager2 = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);
recyclerView1 = (RecyclerView) findViewById(R.id.recycler_restaurant);
recyclerView1.setLayoutManager(layoutManager);
recyclerView2 = (RecyclerView) findViewById(R.id.recycler_restaurant2);
recyclerView1.setLayoutManager(layoutManager2);
loadAsianFood();
loadSteakHouse();
}
private void loadSteakHouse() {
adapter.startListening();
recyclerView1.setAdapter(adapter);
recyclerView1.getAdapter().notifyDataSetChanged();
recyclerView1.scheduleLayoutAnimation();
}
private void loadAsianFood() {
adapter2.startListening(); // Did you mean adapter2.startListening()?
recyclerView2.setAdapter(adapter2);
recyclerView2.getAdapter().notifyDataSetChanged();
recyclerView2.scheduleLayoutAnimation();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
adapter2.stopListening();;
}
#Override
protected void onResume() {
super.onResume();
if (adapter != null)
adapter.startListening();
adapter2.startListening();
}
}
I am using a FirestoreRecyclerAdapter to show items in a RecyclerView. When i call adapter.startListening(); in my activity's onStart() the adapter is empty at run-time. I decided to register a listener to the same query as that of the adapter and pass the list of Objects to the adapter's onBindViewHolder and it works perfectly. here's my adapter
private void loadList(Query query) {
recycler.setHasFixedSize(true);
LinearLayoutManager manager = new LinearLayoutManager(this);
recycler.setLayoutManager(manager);
FirestoreRecyclerOptions<Post response = new FirestoreRecyclerOptions.Builder<Post()
.setQuery(query, Post.class)
.build();
adapter = new FirestoreRecyclerAdapter<Post, PostViewHolder(response) {
#Override
protected void onBindViewHolder(PostViewHolder holder, int position, Post model) {
//holder.setData(postList.get(position));
holder.setData(model);
}
#Override
public PostViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.post_layout, parent, false);
return new PostViewHolder(view);
}
#Override
public void onError(FirebaseFirestoreException e) {
Log.e("error", e.getMessage());
}
};
adapter.notifyDataSetChanged();
recycler.setAdapter(adapter);
}
My adapter is always empty without this registered listener:
firestoreListener = query
.addSnapshotListener(new EventListener<QuerySnapshot() {
#Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
if (e != null) {
//Log.e(TAG, "Listen failed!", e);
return;
}
postList = new ArrayList<();
for (DocumentSnapshot doc : documentSnapshots) {
Post post = doc.toObject(Post.class);
postList.add(post);
}
adapter.notifyDataSetChanged();
recycler.setAdapter(adapter);
}
});
Is this how it normally should be done? I thought the query passed to the adapter in the FirestoreRecyclerOptions was sufficient and the adapter was going to start listening when i call adapter.startListening();
I am trying to search for the information in my firebase db, and I am not able to do so.
This is the class in which I'm searching from:
private FirebaseRecyclerAdapter<DjProfile, ResultsViewHolder> firebaseRecyclerAdapter;
public static Query query;
public static String searchData;
DatabaseReference mProfileDatabase;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_attendee_landing);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final RecyclerView recyclerView = findViewById(R.id.results_recycler);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
final EditText t = (EditText) findViewById(R.id.DjNameET);
mProfileDatabase = FirebaseDatabase.getInstance().getReference();
t.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
if(i == EditorInfo.IME_ACTION_SEARCH)
{
searchData = t.getText().toString();
return true;
}
return false;
}
});
ImageButton imgB= (ImageButton) findViewById(R.id.searchBtn);
imgB.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view)
{
query = mProfileDatabase.orderByChild("djprofile")
.startAt(searchData)
.endAt(searchData + "\uf8ff");
}
});
FirebaseRecyclerOptions<DjProfile> firebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<DjProfile>()
.setQuery(query, DjProfile.class)
.build();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<DjProfile, ResultsViewHolder>(firebaseRecyclerOptions)
{
#NonNull
#Override
public ResultsViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.searchitem_list, viewGroup, false);
return new ResultsViewHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull ResultsViewHolder holder, int position, #NonNull DjProfile model) {
holder.setDjProfile(model);
}
};
recyclerView.setAdapter(firebaseRecyclerAdapter);
}
#Override
protected void onStart()
{
super.onStart();
firebaseRecyclerAdapter.startListening();
}
Here is the exception I am getting: (says to be occuring in the onStart() method)
java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.firebase.database.ChildEventListener com.google.firebase.database.Query.addChildEventListener(com.google.firebase.database.ChildEventListener)' on a null object reference
Any help as to why this is null would be greatly appreciated!
To be able to initialize the adapter, you need to have a valid query. And to be able to create the query, you need to have the searchData. This means that the initialization of the firebaseRecyclerAdapter should happen inside the onClick.
imgB.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view)
{
query = mProfileDatabase.orderByChild("djprofile")
.startAt(searchData)
.endAt(searchData + "\uf8ff");
FirebaseRecyclerOptions<DjProfile> firebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<DjProfile>()
.setQuery(query, DjProfile.class)
.build();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<DjProfile, ResultsViewHolder>(firebaseRecyclerOptions)
{
#NonNull
#Override
public ResultsViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.searchitem_list, viewGroup, false);
return new ResultsViewHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull ResultsViewHolder holder, int position, #NonNull DjProfile model) {
holder.setDjProfile(model);
}
};
recyclerView.setAdapter(firebaseRecyclerAdapter);
}
});
I've checked each and every bit of code in order to successfully render the data on recyclerview from Firebase, but still cannot figure out the problem.
Nothing is show on the logcat when I use Log.d for getting the children of the snapshot(means line is not executed). Can anybody point out the error.
public class MyOrders extends AppCompatActivity {
private static final String TAG = "MyOrders";
DatabaseReference databaseReference;
FirebaseRecyclerAdapter firebaseRecyclerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_orders);
RecyclerView myOrderList = findViewById(R.id.myOrderList);
Query query = FirebaseDatabase.getInstance().getReference("Requests").orderByChild("name").equalTo(User.currentUser.getUserName());
FirebaseRecyclerOptions<Request> options = new FirebaseRecyclerOptions.Builder<Request>().setQuery(query, new SnapshotParser<Request>() {
#NonNull
#Override
public Request parseSnapshot(#NonNull DataSnapshot snapshot) {
Log.d(TAG, "onCreate: "+snapshot.getChildrenCount());
return new Request(snapshot.child("name").getValue().toString(), snapshot.child("phone").getValue().toString(), snapshot.child("address").getValue().toString(), snapshot.child("total").getValue().toString());
}
}).build();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Request, MyOrdersViewHolder>(options){
#NonNull
#Override
public MyOrdersViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.my_order_template, viewGroup, false);
return new MyOrdersViewHolder(v);
}
#Override
protected void onBindViewHolder(#NonNull MyOrdersViewHolder holder, int position, #NonNull Request model) {
Log.d(TAG, "onCreate: "+position);
holder.setOrder_id(firebaseRecyclerAdapter.getRef(position).getKey());
holder.setOrder_status(model.getOrderStatus());
holder.setOrder_items(model.getRequestedOrderList().size()+"");
holder.setItemClickLitener(new ItemClickLitener() {
#Override
public void onClick(View v, int pos, boolean isLongClick) {
Toast.makeText(MyOrders.this, ""+"Pending Action", Toast.LENGTH_SHORT).show();
}
});
}
};
myOrderList.setAdapter(firebaseRecyclerAdapter);
}
#Override
protected void onStart() {
super.onStart();
firebaseRecyclerAdapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
firebaseRecyclerAdapter.stopListening();
}
}