How to handle results from Firebase seeing that its aynchronous - java

How do I return combinedFoodItem from the code below. I have been using firebase for less than a week now and I still find this confusing. The summary is:
Food contains name and categoryId (which is from the FoodOption model)
public void getFoodItems() {
//get all the food options for the selected venue
final List<FoodItem> combinedFoodItem = new ArrayList<>();
filterRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
final FoodOption foodOption = dataSnapshot1.getValue(FoodOption.class);
final List<Food> foodList = new ArrayList<>();
meniItemFilter = menuItemReference.orderByChild("categoryId").equalTo(foodOption.getKey());
meniItemFilter.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot2 : dataSnapshot.getChildren()) {
Food food = dataSnapshot2.getValue(Food.class);
foodList.add(food);
}
FoodItem foodItem = new FoodItem(foodOption.getFoodCategory(), foodList, R.drawable.ic_banjo);
combinedFoodItem.add(foodItem);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}

as firebase works in a reactive manner you can't return elements but listen for changes of them. You can define your combinedFoodItem outside the function (this is, for instance, as a class field) and then add the elements to the list (or clear the list every time the data changes if you want to reset the list this depends on the behavior of your list)

Related

Firebase get vaule of serial number

How to get the value of this automatically without writing each one separately.
I tried this
FirebaseDatabase.getInstance().getReference().child("Orutmen").child("episodeNumber");
but it shows null value.
This one works, but I have to write for each field:
FirebaseDatabase.getInstance().getReference().child("Orutmen").child("1").child("episodeNumber");
Here is the code
m2Database = FirebaseDatabase.getInstance().getReference().child("Orutmen");
m2Database.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String value = snapshot.child("episodeNumber").getValue(String.class);
Toast.makeText(EpisodeListModel.this, value, Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
You can iterate throught the children of DataSnapshot:
m2Database = FirebaseDatabase.getInstance().getReference().child("Orutmen");
m2Database.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String value;
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
value = snapshot.child("episodeNumber").getValue(String.class);
Toast.makeText(EpisodeListModel.this, value, Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
I figured out a way
Just added a list of strings that collects the values from the snapshot
then retrieve the value by position of item clicked >>
List<String> List = new ArrayList<>();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
String value = snapshot.getKey();
List.add(value);
}
Toast.makeText(EpisodeListModel.this, List.get(position), Toast.LENGTH_SHORT).show();

how to get specific nodes under unique keys in firebase realtime database android

I am trying to get data from nested nodes under unique keys. Each key is identical. It's difficult for me to deal with such problem help please.
I have tried ChildEventListener on database reference but not succeeded.
here is the code i am using to retreive data
InfoFragment.java
auth = FirebaseAuth.getInstance();
mFirebaseDatabase = FirebaseDatabase.getInstance().getReference("Seller").getRef().child("ImpInfo");
mFirebaseDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot postDataSnapshot : dataSnapshot.getChildren()) {
ShopSellerInfo shopSellerInfo = postDataSnapshot.getValue(ShopSellerInfo.class);
mShopSellerInfo.add(shopSellerInfo);
}
mNearBySellerAdapter = new NearBySellerAdapter(getContext(), mShopSellerInfo);
mRecyclerView.setAdapter(mNearBySellerAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
return rootView;`
ShopSellerInfo.java
public ShopSellerInfo(String shopAddress, String shopPhoneNo, String
shopImageUrl, String shopName) {
this.shopAddress = shopAddress;
this.shopPhoneNo = shopPhoneNo;
this.shopImageUrl = shopImageUrl;
this.shopName = shopName;
}
public ShopSellerInfo() {
}
public String getShopAddress() {
return shopAddress;
}
public String getShopPhoneNo() {
return shopPhoneNo;
}
public String getShopImageUrl() {
return shopImageUrl;
}
public String getShopName() {
return shopName;
}
public void setUserAddress(String shopAddress) {
this.shopAddress = shopAddress;
}
public void setUserPhoneNo(String shopPhoneNo) {
this.shopPhoneNo = shopPhoneNo;
}
public void setImageUrl(String shopImageUrl) {
this.shopImageUrl = shopImageUrl;
}
public void setShopName(String shopName) {
this.shopName = shopName;
}
}
This is the structure of my Database
I have a specific node in each unique key the contain data. I want to retrieve that data form every child node and show on single activity.
You're not too far off, just a few mistakes. The following is closer to what you need:
mFirebaseDatabase = FirebaseDatabase.getInstance().getReference("Seller");
mFirebaseDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot sellerSnapshot : dataSnapshot.getChildren()) {
DataSnapshot impInfoSnapshot = sellerSnapshot.child("ImpInfo");
ShopSellerInfo shopSellerInfo = impInfoSnapshot.getValue(ShopSellerInfo.class);
mShopSellerInfo.add(shopSellerInfo);
mNearBySellerAdapter = new NearBySellerAdapter(getContext(), mShopSellerInfo);
mRecyclerView.setAdapter(mNearBySellerAdapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
Changes:
Removed the call to .getRef(), which is not needed and in general an anti-pattern.
Removed the call to .child("ImpInfo") from the DatabaseReference, since there is no /Seller/ImpInfo.
Added .child("ImpInfo") in the loop, since you want the ImpInfo child of each snapshot.
Raise an error if onCancelled triggers, since it's a bad practice to ignore errors.

Get number of unique children in an Array/dataSnapshot?

The code below allows me to get the number of children inside the dataSnapshot.
public void onDataChange(DataSnapshot dataSnapshot) {
long numberChildren = dataSnapshot.getChildrenCount();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
My question is how do I get the number of unique children? Something like this would work perfectly: dataSnapshot.getUniqueChildrenCount()
Approach without using set:
ArrayList<String> values=new ArrayList<String>();
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
String children = childDataSnapshot.getValue(String.class);
if (!values.contains(children)) {
values.add(newValue);
}
}
approach using set:
Set<String> set = new HashSet<String>();
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
String children = childDataSnapshot.getValue(String.class);
set.add(children);
}

I want to retrieve all user's UID from Firebase user array and store it into Arraylist

databaseReference.child("user").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
String requests = postSnapshot.getValue(String.class);
req.add(requests);
adapter = new ChallengeSuggestionAdapter(getActivity(), req);
recyclerView.setAdapter(adapter);
}
}
Thanks for helping :)
You're recreating the adapter within the loop. Don't do that.
final List<String> req = new ArrayList<>();
final ChallengeSuggestionAdapter adapter = new ChallengeSuggestionAdapter(getActivity(), req);
recyclerView.setAdapter(adapter);
databaseReference.child("user").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
req.clear();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
String requests = postSnapshot.getValue(String.class);
req.add(requests);
}
recyclerView.notifyDataSetChanged();
}
});
Also, I don't think getValue(String.class) is correct, but you've not expanded your Firebase nodes, so hard to say.
If you want that UUID, you would use req.add(postSnapshot.getKey())
Create GenericTypeIndicator to pass value from DataSnapshot.getValue() parameter.
Look:-
GenericTypeIndicator<List<String>> typeIndicator = new GenericTypeIndicator<List<String>>() {};
List<String> stringArrary = dataSnapshot.getValue(typeIndicator );
Please Use getKey if you want the uid and take your recyclerview adapter from the loop. try using addValueEventListener
databaseReference.child("user").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
req.clear();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
String requests = postSnapshot.getKeyString.class);
req.add(requests);
}
adapter = new ChallengeSuggestionAdapter(getActivity(), req);
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

How to retrieve specific list of data from firebase

I am new to firebase and nosql database
I am trying to retrieve some specific data from a Firebase. I have a node universities and that node has many unique identifier as node which has so more data into it. I want to retrieve name from each node.
Please have a look at this.
What I have tried so far: I tried using addChildEventListener but this only listens first child. I've debugged it and it was only showing the values of the first child of universities node.
myRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
List<University> university = new ArrayList<>();
Map<String, Object> td = (HashMap<String, Object>) dataSnapshot.getValue();
Log.d("TAG",dataSnapshot.getValue().toString());
}
#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) {
}
});
I have also tried addValueEventListener. This listens the whole node and return whole data, but I am unable to extract "name" for it since it contains unique identifiers.
Please guide me into the right directions.
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
University university = dataSnapshot.getValue(University.class);
List<University> universities = (List<University>) dataSnapshot.getValue(University.class);
*//*List<String> lst = new ArrayList<String>();
for(DataSnapshot dsp : dataSnapshot.getChildren()){
lst.add(dsp.getKey());
}
Log.d("TAG",lst.toString());*//*
Map<String, Object> td = (HashMap<String, Object>) dataSnapshot.getValue();
*//*List<Object> values = new ArrayList<Object>(td.values());
List<String> list=new ArrayList<String>();
for(int i=0; i<values.size(); i++){
list.add((String) values.get(i));
}*//*
Log.d("TAG", university.toString());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
If you using addValueEventListener for retrieve all university from Firebase
List<University> universityList = new ArrayList<>();
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
universityList.clear();
for (DataSnapshot postSnapshot: snapshot.getChildren()) {
University university = postSnapshot.getValue(University.class);
universityList.add(university);
// here you can access to name property like university.name
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + firebaseError.getMessage());
}
});
Or if you using addChildEventListener
List<University> universityList = new ArrayList<>();
myRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
University university = dataSnapshot.getValue(University.class);
universityList.add(university);
Log.i(TAG,"add university name = " + university.name);
...
}
...
}
Regarding Linh's answer about using the addEventListener method. You can use GenericTypeIndicator in order to directly create the list of objects you'll be needing. Here's a quick example:
List<University> universityList = new ArrayList<>();
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
GenericTypeIndicator<List<University>> t = new GenericTypeIndicator<List<University>>() {};
universityList = snapshot.getValue(t);
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + firebaseError.getMessage());
}
});
Hope this answer helps.
You can use equalTo() of Query in which you can pass your custom string to match with firebase database.
like this way you can create your Query and set listener with that
Query queryRef = myFirebaseRef.orderByChild("name").equalTo("some name");
refer this thread for more.
Here is nice example from firebase officials, refer that and you will get clear idea
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
User user = postSnapshot.getValue(User.class);
list.add(user);
}
}
class User
class User{
String name;
String phone;
public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
}
public String getphone() {
return phone;
}
public void setphone(String phone) {
this.phone = phone;
}
List bind with class
List<User> list== new ArrayList <>();
100% it will work
I had the same problem .You can just change the access specifier i.e public to private in the Model class you problem will be solved

Categories