How to pull data from firebase which has multiple child? - android

I am trying to pull the data from my firebase real time database. The problem i am facing here is that I can pull the data from /ItemList successfully but when I try to pull the data from /ItemRequest the data cant be pulled but when I give it a specific path such as /ItemRequest/admin it works. What I am trying to do is to populate a listview with all the child from /ItemRequest from both admin and user.I am using firebase list adapter to populate my listview so are there any ways to do what i want?
Database Layout

What I am trying to do is to populate a listview with all the child from /ItemRequest from both admin and user.
To solve this, you need to iterate over the DataSnapshot object twice, like in the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference itemRequestRef = rootRef.child("ItemRequest");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dSnapshot : dataSnapshot.getChildren()) {
for(DataSnapshot ds : dSnapshot.getChildren()) {
String productName = ds.child("ProductName").getValue(String.class);
Log.d(TAG, productName);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
itemRequestRef.addListenerForSingleValueEvent(valueEventListener);
The output in your logcat will be:
Manix
Manix
Manix
If you want to display those results in a ListView, please see my answer from this post:
Showing Firebase data in ListView

AFAIK, FirebaseListAdapter does not work well with child objects that have multiple childs themselves and there is no query method for you to filter them out. I would rather manually pull the child items one by one using DataSnapshots adding them into an arraylist then populating the list using a custom array adapter instead

Related

How to get values from different child in firebase realtime database?

Here is my Database architecture where Jobs is the main child and under that there will be users child, and an user can post multiple time. now i want to get all the posts done by all the users at once. is it possible to do that?
https://i.stack.imgur.com/DT3MO.jpg
setQuery(FirebaseDatabase.getInstance().getReference().child("Jobs")
Used that query to get all of the posts from all of the users but didnt work. any better solution for this problem?
setQuery(FirebaseDatabase.getInstance().getReference().child("Jobs").child("Uid");
this one works but cant use this one because i want to set free for all users to read data.
You can do the following:
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Jobs");
reference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()){
String key = ds.getKey();
for (DataSnapshot childSnapshot: ds.getChildren()) {
// get the child attribute under the random key
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
Since you have a reference to node Jobs then in the first iteration you can get the random keys (highlighted in your image), and in the second iteration you can get the attributes inside those keys.

Retrieving Data from Firebase Realtime DB

This my Firebase database:
This is my code for retrieving data in to list view, I want to get all data from Tehsil_hin and Tid with specific id in two different arraylist.
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("Tehsil");
Query query = myRef.orderByChild("DID").equalTo(did);
query.addValueEventListener(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot postSnapshot: snapshot.getChildren())
{
areas.add(snapshot.child("Tehsil_Hin").getValue(String.class));
areasid.add(snapshot.child("TID").getValue(int.class));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
//System.out.println("The read failed: " + firebaseError.getMessage());
}
});
I'm not reciving data from that
You're never notifying an adapter that data was updated, so no listview will get updated
You need to notify an adapter outside the loop, assuming the loop is in fact entered (please add log statements to debug further)
You should also keep the error method body uncomment because that also is an area where you're not seeing anything happening
If you want to access the data from those children nodes, instead of using query you can just use DatabaseReference and using orderByChild() and equalTo() can access the data which only has the value you want.
In code it looks something like this:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference().child("Tehsil");
// specificTID is the value which you want to compare to the value stored in database
rootRef.orderByChild("TID").equalTo(specificTID).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot data: dataSnapshot.getChildren()){
// use array1.add to store value in your arrayList
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Now you have to update the value to the ArrayAdapter and set it up to your listView to be able to display the data.
ArrayAdapter adapter = new ArrayAdapter(Main2Activity.this, android.R.layout.simple_list_item_1, array);
listView.setAdapter(adapter);
You can do this with both of your children and store the values in different arrays. You can also use different listViews to display the data.

Firebase and recyclerView

Hi I'm new in firebase and android studio and I have a problem
I want to store the data of this database in an array and next use the array to make a recycler view
Then in the main activity I wrote this:
And if I run the app only this is shown:
But if I do the same but instead of firebase i use a String[] with the data i want to show it works but i don't know why with firebase i can't.
if I change the references by this:
reference = database.getReference(FirebaseReferences.POKEMONS_REFERENCES);
reference.child(FirebaseReferences.APP_REFERENCES).addValueEventListener(new ValueEventListener() {
when I run the app, it automatically closes and i don't know what to do.
Could you please tell me what i'm doing wrong?
Thank you in advance.
Here is the logCat
https://github.com/adcasna/SearchViewPrueba2/wiki
Fisrts of all, please note that the Firebase documentation recommends against using arrays. Using an array is an anti-pattern when it comes to Firebase. One of the many reasons Firebase recommends against using arrays is that it makes the security rules impossible to write. If you still want to use this kind of structure, for getting those names and store them in an ArrayList, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference appRef = rootRef.child("pokemons").child("app");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> list = new ArrayList<>();
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String c_name = ds.child("c_name").getValue(String.class);
list.add(c_name);
Log.d("TAG", c_name);
}
Log.d("TAG", list );
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
appRef.addListenerForSingleValueEvent(eventListener);

Retrieving data from Firebase Realtime Database in Android

I'm new to Firebase and NoSQL. I have an Android Demo, with a City Autocomplete Text Field in which I want to populate the cities I have from my Firebase DB, while typing.
{ "cities":{
"Guayaquil":true,
"Gualaceo":true,
"Quito":true,
"Quevedo":true,
"Cuenca":true,
"Loja":true,
"Ibarra":true,
"Manta":true
}
}
This is what I have so far.
How can I retrieve from the DB cities that start with a letter (input from keyboard)? If I start typing "G", I want to receive "Guayaquil" and "Gualaceo".
If I use orderByValue always returns an empty snapshot.
If I use orderByKey return the whole list.
Query citiesQuery = databaseRef.child("cities").startAt(input).orderByValue();
citiesQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> cities = new ArrayList<String>();
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
cities.add(postSnapshot.getValue().toString());
}
Note: If you can recommend a better data structure, you're welcome.
#NicholasChen has identified the problem. But here's the way you'd implement using the 3.x SDK:
DatabaseReference cities = databaseRef.child("cities")
Query citiesQuery = cities.orderByKey().startAt(input).endAt(input+"\uf8ff");
citiesQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> cities = new ArrayList<String>();
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
cities.add(postSnapshot.getValue().toString());
}
By starting at the user input and ending at the last string that starts with the user input, you get all matching items
For relatively short lists of items Ryan's approach will also work fine. But the above Firebase query will filter server-side.
Update
I just ran this code:
DatabaseReference databaseRef = FirebaseDatabase.getInstance().getReference("39714936");
String input = "G";
DatabaseReference cities = databaseRef.child("cities");
Query citiesQuery = cities.orderByKey().startAt(input).endAt(input + "\uf8ff");
citiesQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> cities = new ArrayList<String>();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
cities.add(postSnapshot.getValue().toString());
}
System.out.println(cities);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
And it printed:
true
true
So clearly matches two cities.
Feel free to test against my database: https://stackoverflow.firebaseio.com/39714936
Try something like this to iterate over the children in the cities snapshot and add all the cities to an ArrayList of Strings.
ArrayList<String> cityList = new ArrayList<>();
databaseRef.child("cities").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
cityList.clear();
for (DataSnapshot data : dataSnapshot.getChildren()){
cityList.add(data.getKey);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "getUser:onCancelled", databaseError.toException());
// ...
}
});
Editing this paragraph for clarity:
This will get all your cities read into the program memory so you can use that data to display the cities to the user. If the city list changes, so will the data the user sees. If the user is not online, this will not work. This puts a real time, online only listener on the database.
The logic in my mind is something like:
Set a value listener on the text box.
When user types, make a view display all the items in the array list
that start with the same substring that was typed.
Handle arrayIndex errors of course.
Hopefully this will get you on the right track. I am sure there are other ways you could implement it but this is what I would personally do. If you need help with the code to display the correct cities, start a chat with me and I can brainstorm with you.
Of course OrderByValue returns nothing because that's the booleans you have.
you can use the startAt and endAt methods to do so. (The below is Firebase 2.0's Code)
var ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs");
ref.orderByKey().startAt("b").endAt("b\uf8ff").on("child_added", function(snapshot) {
console.log(snapshot.key());
});
You can explore more on the Firebase 3 documentation site here.
What Ryan did was right. However, you have to implement startAt on the dataSnapshot to make sure that your "live" search works.

Filter the results received from firebase before supplying it to the Firebase List adapter

I am new to firebase and android.
I am populating a listview with data from firebase using firebase List adapter.
I understand that we can not chain filters in firebase.
Below is the code snippet from the activity. I created a firebase reference. Then I applied the equalTo filter to get items with category=clothes.
Query orderedActiveUserListsRef;
Firebase activeListsRef = new Firebase(Constants.FIREBASE_URL_USER_LISTS)
.child(mEncodedEmail);
orderedActiveUserListsRef = activeListsRef.orderByChild("category").equalTo("clothes");
I would like to further filter out results from orderedActiveUserListsRef before supplying it to the adapter.
One approach I found is creating an array by iterating the orderedActiveUserListsRef using the below code:
orderedActiveUserListsRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot messageSnapshot: dataSnapshot.getChildren()) {
String category = (String) messageSnapshot.child("category").getValue();
Log.d("CatList",category);
}
}
#Override
public void onCancelled(FirebaseError firebaseError) { }
});
Please advise the best possible approach.
PS: I have denormalised the data.

Categories

Resources