querying multipe documents of acollection - android

image of databaseI have a collection in the firebase firestore inside which I have multiple documents. I want to retrieve a document based on the data field which is present in the document how can I do this in android.
I have done this
firebaseFirestore = FirebaseFirestore.getInstance();
CollectionReference collectionReference = firebaseFirestore.collection("Planes");
Query query = collectionReference.whereEqualTo("starting",startAirport).whereEqualTo("destination",destinationAirport);
FirestoreRecyclerOptions<Planes> response = new FirestoreRecyclerOptions.Builder<Planes>()
.setQuery(query, Planes.class)
.build();
firestoreRecyclerAdapter= new FirestoreRecyclerAdapter<Planes,PlaneViewHolder>(response) {
#NonNull
#Override
public PlaneViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.planes_item,parent,false);
return new PlaneViewHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull PlaneViewHolder holder, int position, #NonNull Planes model) {
holder.book.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DocumentSnapshot snapshot = getSnapshots().getSnapshot(holder.getAdapterPosition());
final String DocId= snapshot.getId();
Intent intent=new Intent(PlaneRequestActivity.this,UserDetails.class);
intent.putExtra("Document",DocId);
intent.putExtra("tripId",tripId);
startActivity(intent);
}
});
holder.setPlanes(model);
}
#Override
public void onError(#NonNull FirebaseFirestoreException e) {
super.onError(e);
Toast.makeText(PlaneRequestActivity.this,"Error:"+e.toString(),Toast.LENGTH_LONG).show();
}
};
plane.setAdapter(firestoreRecyclerAdapter);
}
it works for only the first document. It didn't find the second Document of the Collection

Related

Getting a list inside a firestore document into a recyclerview

i have a document inside firestore, that document also has a list inside is called "foods". I want to be able to load only that list of "foods" into a recyclerview, I'm not sure how to query the list for recycler options. Here is what the DB structure looks like:
Here is my Adapter
List<Order> myOrders;
public OrderDetailAdapter(#NonNull FirestoreRecyclerOptions<Order> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull OrderDetailAdapter.DetailsHolder holder, int position, #NonNull Order model) {
Order order = myOrders.get(position);
holder.product_name.setText(model.getProductName());
holder.product_price.setText(model.getPrice());
holder.product_quantity.setText(model.getQuantity());
holder.product_discount.setText(model.getDiscount());
}
#NonNull
#Override
public OrderDetailAdapter.DetailsHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.order_item_layout, parent,false);
return new DetailsHolder(v);
}
public class DetailsHolder extends RecyclerView.ViewHolder {
TextView product_name, product_price, product_discount, product_quantity;
public DetailsHolder(#NonNull View itemView) {
super(itemView);
product_name = itemView.findViewById(R.id.product_name);
product_price = itemView.findViewById(R.id.product_price);
product_discount = itemView.findViewById(R.id.product_discount);
product_quantity = itemView.findViewById(R.id.product_quantity);
}
}
#Override
public int getItemCount() {
return myOrders.size();
}
}
Here is my Activity:
private FirebaseFirestore db = FirebaseFirestore.getInstance();
DocumentReference documentReference;
TextView order_id, order_comment, order_date, order_total;
String order_id_value ="";
RecyclerView lstFoods;
RecyclerView.LayoutManager layoutManager;
OrderDetailAdapter orderAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_order_details);
if (getIntent() !=null)
order_id_value = getIntent().getStringExtra("order_number");
documentReference = db.collection("Requests").document(order_id_value);
lstFoods = findViewById(R.id.food_list);
lstFoods.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
lstFoods.setLayoutManager(layoutManager);
order_id.setText(order_id_value);
documentReference.addSnapshotListener(new EventListener<DocumentSnapshot>() {
#Override
public void onEvent(#Nullable DocumentSnapshot documentSnapshot, #Nullable FirebaseFirestoreException e) {
if (documentSnapshot.exists()){
Order order = documentSnapshot.toObject(Order.class);
orderAdapter.notifyDataSetChanged();
lstFoods.setAdapter(orderAdapter);
}else{
Log.d("TAG", "ERROR");
}
}
});
}
#Override
protected void onStart() {
super.onStart();
orderAdapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
orderAdapter.stopListening();
}
}
When i try to run it i get the following error:
error: incompatible types: List cannot be converted to FirestoreRecyclerOptions
super(options);

How to implement ViewModel with FirebaseRecyclerAdapter

I am trying to separate my database from my UI controller using ViewModel and prevent constant data usage. I have searched for solution for days now without any headway.
I am using Firebase RecyclerAdapter in my app and the code is working well, but I don't know how to implement a LiveData Observer with the RecyclerAdapter.
any sample app or snippet will be of great help to me.
Here is a sample code from my Fragment
private void fetchValues() {
Query query1 = mDatabaseReference;
FirebaseRecyclerOptions<Course> options = new FirebaseRecyclerOptions.Builder<Course>()
.setQuery(query1, new SnapshotParser<Course>() {
#NonNull
#Override
public Course parseSnapshot(#NonNull DataSnapshot snapshot) {
return new Course(snapshot.child("course_title").getValue().toString(),
snapshot.child("course_code").getValue().toString(),
snapshot.child("course_lecturer").getValue().toString());
}
})
.build();
mFirebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Course, CourseViewHolder>(options){
#NonNull
#Override
public CourseViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
mCourseItemBinding = CourseItemBinding.inflate(LayoutInflater.from(getActivity()), parent, false);
View view = mCourseItemBinding.getRoot();
return new CourseViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CourseViewHolder holder, int position, Course course) {
holder.bind(course);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getActivity(), String.valueOf(position), Toast.LENGTH_LONG).show();
}
});
}
};
mRecyclerView.setAdapter(mFirebaseRecyclerAdapter);
}

Recycler View showing only very last item added to realtime database

I have a firebase strucuture as
The recycler view is only displaying the last added or say latest added node to the database instead of displaying each and every node
the database reference i am using is
r2 = FirebaseDatabase.getInstance().getReference().child("Uploads").child("Wheat").child(S).child(D).child(T).child(FirebaseAuth.getInstance().getUid());
and the code for recycler view is as
public class MyPost extends AppCompatActivity {
private RecyclerView recyclerView;
private DatabaseReference r, r2, r3;
private String S, D, T;
FirebaseRecyclerAdapter<RecyclerCropView, ViewHolder2> Fbra1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_post);
r = FirebaseDatabase.getInstance().getReference().child("User_Data").child(MainDashboard.type).child(FirebaseAuth.getInstance().getUid());
recyclerView = (RecyclerView) findViewById(R.id.R_view2);
r.addListenerForSingleValueEvent(rr);
}
private ValueEventListener rr = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
S = dataSnapshot.child("State").getValue().toString();
D = dataSnapshot.child("City").getValue().toString();
T = dataSnapshot.child("Tehsil").getValue().toString();
// Toast.makeText(MyPost.this,S+D+T.toString(),Toast.LENGTH_LONG).show();
r2 = FirebaseDatabase.getInstance().getReference().child("Uploads").child("Wheat").child(S).child(D).child(T).child(FirebaseAuth.getInstance().getUid());
// Toast.makeText(MyPost.this,r2.toString(),Toast.LENGTH_LONG).show();
r2.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
r3=r2.child(dataSnapshot.getKey());
Toast.makeText(MyPost.this, r3.toString(), Toast.LENGTH_LONG).show();
FirebaseRecyclerOptions<RecyclerCropView> options = new FirebaseRecyclerOptions.Builder<RecyclerCropView>().setQuery(r3, RecyclerCropView.class).build();
Fbra1 = new FirebaseRecyclerAdapter<RecyclerCropView, ViewHolder2>(options) {
#Override
protected void onBindViewHolder(#NonNull ViewHolder2 holder, int position, #NonNull RecyclerCropView model) {
holder.setProductImage(model.getProduct_Image());
holder.setProduct(model.getProduct());
holder.setMax(model.getMaximumPrice());
holder.setQuantityUnit(model.getQuantityUnit());
holder.setQuantity(model.getQuantity());
}
#NonNull
#Override
public ViewHolder2 onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_post, parent, false);
return new ViewHolder2(v);
}
};
Fbra1.notifyDataSetChanged();
recyclerView.hasFixedSize();
recyclerView.setLayoutManager(new LinearLayoutManager(MyPost.this));
Fbra1.startListening();
recyclerView.setAdapter(Fbra1);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
#Override
protected void onRestart() {
super.onRestart();
finish();
}
}
Recycler view is only showing very last item that was added to database.
Note:-
The item.xml file has width set to wrap content.
if i remove the childEventListener the recyclerView shows multiple items with
null on the place of TextView(These are those textView on which data retrived was supposed to be set)
Here is the problem: r2.addChildEventListener
Classes implementing this interface can be used to receive events about changes in the child locations of a given DatabaseReference ref. Attach the listener to a location using addChildEventListener(ChildEventListener) and the appropriate method will be triggered when changes occur.
Firebase Docs
What you should use is a r2.addListenerForSingleValueEvent
This returns the children of the specific node. But now since you are using FirebaseUI library, you will not need to listen as it is a listener itself.
So your code should listen to the root of the posts. This r3=r2.child(dataSnapshot.getKey()); is unnecessary because it only gets one entry
Change to this
FirebaseRecyclerOptions<RecyclerCropView> options = new FirebaseRecyclerOptions.Builder<RecyclerCropView>().setQuery(r2, RecyclerCropView.class).build();
Fbra1 = new FirebaseRecyclerAdapter<RecyclerCropView, ViewHolder2>(options) {
#Override
protected void onBindViewHolder(#NonNull ViewHolder2 holder, int position, #NonNull RecyclerCropView model) {
holder.setProductImage(model.getProduct_Image());
holder.setProduct(model.getProduct());
holder.setMax(model.getMaximumPrice());
holder.setQuantityUnit(model.getQuantityUnit());
holder.setQuantity(model.getQuantity());
}
#NonNull
#Override
public ViewHolder2 onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_post, parent, false);
return new ViewHolder2(v);
}
};
Fbra1.notifyDataSetChanged();
recyclerView.hasFixedSize();
recyclerView.setLayoutManager(new LinearLayoutManager(MyPost.this));
Fbra1.startListening();
recyclerView.setAdapter(Fbra1);

How to refresh data in FirebaseAdapter using FirebaseUI when query is changed?

I want to allow users to sort and filter data. I have this implementation of Firebase Adapter and everything is working great. When I want to filter data using e.g. price, data in RecyclerView is not changing. Can you please help and tell what am doing wrong?
This is the query - depends on what user selected from Spinner:
Query query;
if (!priceLower.equals("Any")) { // option from Spinner
query = FirebaseDatabase.getInstance()
.getReference()
.child("Students")
.orderByChild("price")
.startAt(priceLower)
.limitToLast(50);
} else if (!priceHigher.equals("Any")) {
query = FirebaseDatabase.getInstance()
.getReference()
.child("Students")
.orderByChild("price")
.endAt(priceHigher)
.limitToLast(50);
} else {
query = FirebaseDatabase.getInstance()
.getReference()
.child("Students")
.orderByChild("price")
.limitToLast(50);
}
getData(query);
This is the method to fetch data from Firebase:
public void getData(Query query) {
FirebaseRecyclerOptions<Students> firebaseOptions =
new FirebaseRecyclerOptions.Builder<Students>()
.setQuery(query, Students.class)
.build();
FirebaseAdapter = new FirebaseRecyclerAdapter<Students, StudentsHolder>(firebaseOptions) {
#NonNull
#Override
public StudentsHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_students, parent, false);
return new StudentsHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull StudentsHolder holder, int position, #NonNull final Students student) {
holder.setName(student.getName());
holder.setPrice(student.getPrice());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// ...
}
});
}
#Override
public void onDataChanged() {
progressDialog.setVisibility(View.GONE);
mRecyclerView.setAdapter(FirebaseAdapter);
}
};
}
To solve this, you should add at the end of your getData() method, the following line of code:
FirebaseAdapter.startListening();
This means that everytime you change the query, you create and set a new adapter and you also start listening for changes.
#Override
public void onDataChanged() {
progressDialog.setVisibility(View.GONE);
mRecyclerView.setAdapter(FirebaseAdapter);
}
This method is called only when data on firebase database is changed. But according to your requirement, this data remains the same and only your applied filter or sorting method is changing. Therefore this method will never be called and firebaseadapter will reflect original query only.
Try it this way:
public void getData(Query query) {
FirebaseRecyclerOptions<Students> firebaseOptions =
new FirebaseRecyclerOptions.Builder<Students>()
.setQuery(query, Students.class)
.build();
FirebaseAdapter = new FirebaseRecyclerAdapter<Students, StudentsHolder>(firebaseOptions) {
#NonNull
#Override
public StudentsHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_students, parent, false);
return new StudentsHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull StudentsHolder holder, int position, #NonNull final Students student) {
holder.setName(student.getName());
holder.setPrice(student.getPrice());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// ...
}
});
}
#Override
public void onDataChanged() {
}
};
progressDialog.setVisibility(View.GONE);
mRecyclerView.setAdapter(FirebaseAdapter);
}
getData() method should be called whenever your filter is changed.

How to load firebase data into recyclerview

I'm seeking help on how to load a data stored in a Firebase Database into a recyclerview.
The below screenshot indicates how I would like for the data to be structured when loaded into the recyclerview.
I am able to access the data from individual paths such as "Upcoming/Events/03/23" using the addEventListener but unable to load dynamically into a recyclerview in the format above.
See Code below that I have below to load the children under the different nodes, but i'm able to load it into the recyclerview
private ListView mUserList;
private ArrayList<String> mUpcomingList = new ArrayList<>();
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1,mUpcomingList);
mUserList.setAdapter(arrayAdapter);
String CurrentString = date.toString().trim();
StringTokenizer tokens = new StringTokenizer(CurrentString, "/");
String first = tokens.nextToken();
String second = tokens.nextToken();
mDatabase = FirebaseDatabase.getInstance().getReference().child("Upcoming/Events").child(first);
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
Public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(TAG,"Listing children");
for (DataSnapshot child: dataSnapshot.getChildren()) {
mUpcomingList.add(child.getKey());
arrayAdapter.notifyDataSetChanged();
}
Your help is appreciated.
when you used then you make recyclerview adatper and bind this adapter into a recycler view . used below code for display firebase all the data and change according your need and make changes.
RecyclerView Adapter::
public class DisplayAllData extends RecyclerView.Adapter<DisplayAllData.ItemViewHolder>{
private List<User> mUserLsit=new ArrayList<>();
private Context mContext;
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout,parent,false);
return new ItemViewHolder(view);
}
public DisplayAllData(Context mContext,List<User> mUserLsit) {
this.mContext=mContext;
this.mUserLsit = mUserLsit;
}
#Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
User user=mUserLsit.get(position);
holder.mTvName.setText(user.name);
holder.mTvEmail.setText(user.email);
holder.mTvPwd.setText(user.pwd);
}
#Override
public int getItemCount() {
return mUserLsit.size();
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
TextView mTvName,mTvEmail,mTvPwd;
public ItemViewHolder(View itemView) {
super(itemView);
mTvEmail=itemView.findViewById(R.id.rlTvEmail);
mTvName=itemView.findViewById(R.id.rlTvName);
mTvPwd=itemView.findViewById(R.id.rlTvPwd);
}
}
}
In Adapter take a simple layout and make three textview control and bind data into that.
then after take activity layout and define recycler view in xml. then after used below code to read firebase database record and display recyclerview.
public class DisplayActivity extends AppCompatActivity {
private RecyclerView mRvData;
private DisplayAllData allDataAdapter;
private DatabaseReference mDatabase;
private TextView mTvEmpty;
private FirebaseDatabase mFirebaseInstance;
private List<User> mUserList = new ArrayList<>();
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.display_data);
initView();
}
private void initView() {
mFirebaseInstance = FirebaseDatabase.getInstance();
mDatabase = mFirebaseInstance.getReference("usersDb/UserTable");
mRvData = findViewById(R.id.rvData);
mTvEmpty = findViewById(R.id.dlTvEmpty);
mRvData.setLayoutManager(new LinearLayoutManager(this));
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mUserList.clear();
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
User user = dataSnapshot1.getValue(User.class);
mUserList.add(user);
}
allDataAdapter = new DisplayAllData(DisplayActivity.this, mUserList);
mRvData.setAdapter(allDataAdapter);
allDataAdapter.notifyDataSetChanged();
if (mUserList.isEmpty())
mTvEmpty.setVisibility(View.VISIBLE);
else
mTvEmpty.setVisibility(View.GONE);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
You have to use FirebaseRecyclerAdapter,
as
FirebaseRecyclerAdapter<Model, ViewHolder> Adapter = new FirebaseRecyclerAdapter<Model, ViewHolder>(
Model.class, //Name of model class
R.layout.row, //Row layout to show data
viewHolder.class, //Name of viewholder class
mDatabaseRef // Database Refernce
) {
#Override
protected void populateViewHolder(VieHolder viewHolder, Model model, int position) {
//Your Method to load Data
}
};
RecyclerView.setAdapter(Adapter);
For this you have to create two other classes, One is viewholder ( to display data) and second model class ( refers to name of nodes from where you are fetching data ).
final DatabaseReference cartListRef = FirebaseDatabase.getInstance().getReference().child("Cart List");
FirebaseRecyclerOptions<Cart> options = new FirebaseRecyclerOptions.Builder<Cart>()
.setQuery(cartListRef.child("User View")
.child(Prevalent.currentOnlineUser.getPhoneNumber())
.child("Products"), Cart.class).build();
FirebaseRecyclerAdapter<Cart, CartViewHolder> adapter =
new FirebaseRecyclerAdapter<Cart, CartViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull CartViewHolder holder, int position, #NonNull final Cart model) {
holder.txtProductQuantity.setText("Quantity = " + model.getQuantity());
holder.txtProductName.setText(model.getPname());
holder.txtProductPrice.setText("Price = " + model.getPrice() + "৳");
int oneTypeProductPrice = ((Integer.valueOf(model.getPrice()))) * Integer.valueOf(model.getQuantity());
overTotalPrices = overTotalPrices + oneTypeProductPrice;
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CharSequence options[] = new CharSequence[]
{
"Edit",
"Remove"
};
AlertDialog.Builder builder = new AlertDialog.Builder(CartActivity.this);
builder.setTitle("Cart Options");
builder.setItems(options, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int i) {
if (i == 0){
Intent intent = new Intent(CartActivity.this, ProductDetailsActivity.class);
intent.putExtra("pid", model.getPid());
startActivity(intent);
}
if (i == 1){
cartListRef.child("User View")
.child(Prevalent.currentOnlineUser.getPhoneNumber())
.child("Products")
.child(model.getPid())
.removeValue()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
Toast.makeText(CartActivity.this,"Item removed successfully.",Toast.LENGTH_LONG).show();
Intent intent = new Intent(CartActivity.this, HomeActivity.class);
startActivity(intent);
}
}
});
}
}
});
builder.show();
}
});
}
#NonNull
#Override
public CartViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cart_items_layout, parent, false);
CartViewHolder holder = new CartViewHolder(view);
return holder;
}
};
recyclerView.setAdapter(adapter);
adapter.startListening();
}

Categories

Resources