Firebase Database - Unable to retrieve nested data - java

I'm unable to retrieve the data which is nested inside "Leagues" and "Season".
In the database below, I cannot retrieve Season 2016/2017 points and results.
I am able to access the data that is not nested, such as Email and Username without problems
"Users" :
"User1" : {
"Email" : "dfs#sdf.com",
"Last_login" : "5:15pm",
"Username" : "Test",
"Leagues" : {
"FootballLeague" : true,
"CricketLeague" : true
},
"Season" : {
"2017" : {
"Points" : 5,
"Results" : 2
"newdata" : {
"randomdata1: data1",
"randomdata2: data2"
},
}
"2018" : {
"Points" : 7,
"Results" : 2
}
}
The following class is what I'm using to store data as objects:
public class Users {
private String Username;
private String Email;
private String Last_login;
private Map<String, Boolean> Leagues;
private Map<String, thisSeason> Season;
public Users() {
}
//All getters and setters for the strings.
public Map<String, Boolean> get_joined_Leagues() {
return Leagues;
}
public void set_joined_Leagues(Map<String, Boolean> leagues) {
Leagues = leagues;
}
public Map<String, thisSeason> getSeason() {
return Season;
}
public void set_thisSeason(Map<String, thisSeason> season) {
Season = season;
}
public static class thisSeason {
private int Points;
private int Results;
private Map <String, thisNewData> newdata;
public thisSeason() {
}
public int getthisSeason_results() {
return Results;
}
public void setthisSeason_results(int resultsin) {
Results = resultsin;
}
public int getthisSeason_points() {
return Points;
}
public void setSeason_points(int Pointsin) {
Points = Pointsin;
}
public Map<String, thisNewData> getNewData() {
return newdata;
}
public void set_thisNewData(Map<String, thisNewData> newdata_in) {
newdata= newdata_in;
}
public static class thisNewData {
private String randomdata1;
private String randomdata2;
//Getters and Setters
}
Here is part of my Java class where I access the Database:
List<Users> usersList= new ArrayList<Users>();
DatabaseReference fbDB = FirebaseDatabase.getInstance().getReference();
fbDB.child("Users").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
Users C = ds.getValue(Users.class);
usersList.add(C);
System.out.println(C.getSeason().getthisSeason_points()); //ERROR occurs here - null object reference
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
I get a null object reference error as shown in the code above.
Also, on a slight side note - I'm aware my implementation for getting Leagues is incorrect. How can I retrieve the keys instead?

The main problems that I found in your code:
First, your Leagues object:
Well, it should not be a custom object at all, if it stays in the current structure, but a Map. This is the map object - a collection which has a key, and a value, just like a child in the Realtime Database.
If a league name (=key) didn't have a true (=value) next to it - the names could have been stored in String variables, but this is not the case, because every child in the Realtime Database must have a value, and storing a "dummy" value next to a league name makes each league a part of a Map. This current "dummy" is a boolean, and that's why this will be the leagues' data type:Map<String, Boolean> leagues.
Second, your Season object:
You are confusing between one season and many seasons. Your child - "Season" actually stores a lot of seasons. Thats why this case will be similar to the one above - each season's time is the key and the season itself is the value.
Therefore, the User class's variables should be:
private String Username;
private String Email;
private String Last_login;
private Map<String,Boolean> Leagues;
private Map<String, Season> Seasons;

Related

How to get out the stored data from Firebase?

I'm not getting the output from Firebase database. It's not returning anything. Here is my data structure.
I also tried getting value through query but it returned database error:
Cannot convert java.util.hashmap to String
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference().child("Member").push();
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String value = ds.getValue(String.class);
Log.d("Tag", "Value is" + value);
}
}
JSON:
{
"Member" : {
"-LhKJVG1Tj2628sHPg4D" : {
"age" : "21",
"name" : "Gagan",
"nickname" : "Gaggi"`enter code here`
},
"-LhKKaNFnPrrh1bQNPfH" : {
"age" : "18",
"name" : "Jashan",
"nickname" : "Jassi"
}
}
}
You cannot call getValue with String.class because it does not meet the criteria of the method call.
From the documentation
public T getValue(Class valueType)
This method is used to marshall the data contained in this snapshot into a class of your choosing. The class must fit 2 simple constraints:
The class must have a default constructor that takes no arguments
The class must define public getters for the properties to be assigned. Properties without a public getter will be set to their default value when an instance is deserialized
An example class might look like:
class Message {
private String author;
private String text;
private Message() {}
public Message(String author, String text) {
this.author = author;
this.text = text;
}
public String getAuthor() {
return author;
}
public String getText() {
return text;
}
}
// Later
Message m = snapshot.getValue(Message.class);
You can use String class
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String name= ds.child("name").getValue(String.class);
String age= ds.child("age").getValue(String.class);
//and similar for others
Log.d("TAG", email + " / " + name);
}
}

Fetching list objects from single document using Cloud Firestore

I have list of object store in single document in Firestore. On my android side i am not able to fetch list of object and their inner data.
Here is code i am trying to fetch data
CollectionReference mCollectionReference = FirebaseFirestore.getInstance().collection("Categories");
mCollectionReference.document("Dinner Dishes").get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
Collection<Object> objectMap = documentSnapshot.getData().values();
for(Object result:objectMap){
Sample obj = Sample.class.cast(result);
HashMap<String, String> pic = obj.getPic();
HashMap<String, String> name = obj.getName();
}
}
});
I need list of object i upload on Firestore in single document
My Model Class:
public class Sample {
private String name;
private String pic;
public Sample() {
}
public String getName() {
return name;
}
public String getPic() {
return pic;
}
}
You can convert it to a java object, if that is how you saved it?
ObjectType myObject = document.toObject(ObjectType.class);

Android - unable to add data to arraylist of string - when data retrieved from firebase

I have a custom list adapter that has many methods that query the database and add data to different java objects or lists.
code to consider in adapter as follows: -
static class ViewHolder {
ArrayList<String> imgUrls;
//other variables;
}
then initiated it in getView method as:-
public View getView(#params) {
holder.imgUrls = new ArrayList<>();
}
//i have a method that query and retrieve data from firebase as follows:-
public void getPhoto(final ViewHolder holder) {
Query query = reference
.child(mContext.getString(R.string.dbname_collections))
.child(holder.collection.getCollection_id())
.child("photo_url");
query.keepSynced(true);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot singleSnapshot : dataSnapshot.getChildren()) {
imgUrl = singleSnapshot.getValue(String.class);
Log.d(TAG, "onDataChange: imgUrl: " + imgUrl);
holder.imgUrls.add(imgUrl);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Log.d(TAG, "getPhoto: list with values " + holder.imgUrls);
}
My database in firebase console look like this:-
{
"collections": {
"-L9nNSyF7ZhEqpvmPo0Z": {
"caption": "jakhaha",
"collection_id": "-L9nNSyF7ZhEqpvmPo0Z",
"date_created": "2018-04-11T11:55:57Z",
"photo_url": [
"https://firebasestorage.googleapis.com/v0/b/backbench-72a47.appspot.com/o/collection%2Fusers%2FHb8ORoozQ3WhyxjaSyqazjHypkf2%2F2018-04-11T11%3A55%3A57Z%2Fphoto0?alt=media&token=08fdb740-9b16-455b-83ec-bfcec1455834",
"https://firebasestorage.googleapis.com/v0/b/backbench-72a47.appspot.com/o/collection%2Fusers%2FHb8ORoozQ3WhyxjaSyqazjHypkf2%2F2018-04-11T11%3A55%3A57Z%2Fphoto1?alt=media&token=eeca4b10-0729-4ca9-be18-c31d054add19",
"https://firebasestorage.googleapis.com/v0/b/backbench-72a47.appspot.com/o/collection%2Fusers%2FHb8ORoozQ3WhyxjaSyqazjHypkf2%2F2018-04-11T11%3A55%3A57Z%2Fphoto2?alt=media&token=b33c97b0-c2bf-4199-bef0-b498f505a678"
],
//this are the imageUrls i want to retrieve as a arrylist
"tags": "#NoTags",
"user_id": "Hb8ORoozQ3WhyxjaSyqazjHypkf2"
}
}
}
in my firebase model class :-
public class Collection implements Parcelable {
//properties for photo (*case sensitive*)
private String caption;
private String date_created;
private String collection_id;
private String user_id;
private String tags;
//list of likes
private List<String> photo_url;
private List<Like> likes;
private List<Comment> comments;
public Collection() {
}
//constructor..getter setters etc...
}
in my log console i see that values of imgUrl are fatched
04-11 20:35:03.992 21269-21269/com.backbenchers.administrator.instaclone D/CollectionListAdapter: onDataChange: imgUrl://url of image 1
onDataChange: imgUrl: url of image 2
onDataChange: imgUrl: ...image 3
but it shows list as null or [] :-
D/CollectionListAdapter: getPhoto: list is with values : []
"I want to fetch this firebase data and add it to an arraylist.."
what is wrong ??
Thanks!

Process array list from map

We are trying to access the array of object that placed inside a map.
Can any one guide us to get length of the array as well as fetching each element from the list. Sample map object given bellow.
{
storeId = 1,
ShipToStreetLine1 = test 123,
ShipToCity = Seattle,
OrderDetails = [{
distributor_name = SS,
product_name = HORN 80897 AM GUN 300BO 125 HP 50/10
}]
}
We need to get the size of orderDetails array and if data present, then I want to fetch product_name.
You can try this:
Create a POJO which is type of what you are getting in orderDetails
Like
public class OrderDetailElement{
private String distributor_name;
private String product_name;
public String getDistributor_name() {
return distributor_name;
}
public void setDistributor_name(String distributor_name) {
this.distributor_name = distributor_name;
}
public String getProduct_name() {
return product_name;
}
public void setProduct_name(String product_name) {
this.product_name = product_name;
}
}
in your logic class you can do is
ArrayList<OrderDetailElement> orderDetails = yourMap.get("OrderDetails");
List<String> products = new ArrayList<String>();
if (orderDetails.size() > 0) {
for (OrderDetailElement orderDetailElement : orderDetails) {
products.add(orderDetailElement.getProduct_name());
}
}

Populate ListView with Firebase Adapter

I'm receiving these errors when I tried to populate a list view with firebase adapter using firebase UI
com.google.firebase.database.DatabaseException: Failed to convert
value of type java.util.HashMap to String
com.google.firebase.database.DatabaseException: Class
java.util.HashMap has generic type parameters, please use
GenericTypeIndicator instead
Here Is the code
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
DatabaseReference a = ref.child("info");
final FirebaseListAdapter<String> adapter =
new FirebaseListAdapter<String>(this,String.class,android.R.layout.simple_list_item_1,a) {
#Override
protected void populateView(View v, String model, int position) {
TextView text = (TextView) findViewById(android.R.id.text1);
text.setText(model);
}
here is an example of json data
"info" : {
"KSTUJILdwPN305Fs7ujhga4knlG3" : {
"File Info" : {
"-JFRkA855rfOU7GtcK4" : {
"Name" : "John",
"Adress" : "Test Adress",
"Favourite_food" : "Bread",
},
info node does not refer to your data model. It may contain children nodes. So to reach the model, you should use a reference like this.
DatabaseReference a = ref.child("info").child(info_id).child("File Info").child(file_id);
and you should have a FileInfo model instead of String model to use in
populateView(View v, FileInfo model, int position):
and model
public class FileInfo {
private String Name;
private String Adress;
private String Favourite_food;
public FileInfo() {
}
public FileInfo(String Name, String Adress, String Favourite_food) {
this.Name = Name;
this.Adress = Adress;
this.Favourite_food = Favourite_food;
}
public String getName() {
return Name;
}
public void setName(String Name) {
this.Name = Name;
}
public String getAdress() {
return Adress;
}
public void setAdress(String Adress) {
this.Adress = Adress;
}
public String getFavourite_food() {
return Favourite_food;
}
public void setFavourite_food(String Favourite_food) {
this.Favourite_food = Favourite_food;
}
}
final FirebaseListAdapter<String> adapter = new FirebaseListAdapter<String>(this,String.class,android.R.layout.simple_list_item_1,a)
public FirebaseListAdapter(Activity activity,
java.lang.Class<T> modelClass,
int modelLayout,
com.firebase.client.Firebase ref)
modelClass - Firebase will marshall the data at a location into an instance of a class that you provide
replace the constructor's 2nd parameter (String.class) with a POJO with the fields from info (name, address, favouriteFood)
FirebaseListAdapter
Edit:
You should also use getters in the populateView method

Categories