How to get all child's data in firebase database? - android

I have this firebase database
and i need to get all phone numbers of users , which listener shall i use to get all childes?
Every user is added as an object with user-ID as a name of that object, I need to retrieve this objects without knowing that user-ID
I searched the documentation , it's related to DataSnapshot but i couldn't get a DataSnapshot without a listener ! is it correct to seek a DataSnapshout or shall i use something else

First retrieve your users datasnapshot.
//Get datasnapshot at your "users" root node
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("users");
ref.addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Get map of users in datasnapshot
collectPhoneNumbers((Map<String,Object>) dataSnapshot.getValue());
}
#Override
public void onCancelled(DatabaseError databaseError) {
//handle databaseError
}
});
Then loop through users, accessing their map and collecting the phone field.
private void collectPhoneNumbers(Map<String,Object> users) {
ArrayList<Long> phoneNumbers = new ArrayList<>();
//iterate through each user, ignoring their UID
for (Map.Entry<String, Object> entry : users.entrySet()){
//Get user map
Map singleUser = (Map) entry.getValue();
//Get phone field and append to list
phoneNumbers.add((Long) singleUser.get("phone"));
}
System.out.println(phoneNumbers.toString());
}
This listener will only retrieve the datasnapshot when explicitly called. Consider storing a list of numbers under an "allPhoneNumbers" node in addition to your users node. This will make your datasnapshots lighter and easier to process when collecting all numbers. If you have say hundreds of users, the "users" datasnapshot will be way too big and the "allPhoneNumbers" list will be far more efficient.
The above code was tested on your sample database and does work. However, your phone field may need to be casted to String or int depending on your user's phone instance field's type.

DatabaseReference ref1= FirebaseDatabase.getInstance().getReference();
DatabaseReference ref2,ref3,ref4;
ref2 = ref1.child("User");
ref2.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Userlist = new ArrayList<String>();
// Result will be holded Here
for (DataSnapshot dsp : dataSnapshot.getChildren()) {
Userlist.add(String.valueOf(dsp.geValue())); //add result into array list
}
/* userlist will store all values of users, then point to every userlist item
and get mobile numbers*/

Related

How to get this type of pattern from firebase android

I'm trying to get the account data from Firebase, note that account can be multiple for example user can store more than 1 account details so i need to get all the account details from this pattern
The code written so far
myRef = FirebaseDatabase.getInstance().getReference("users");
mUserList = new ArrayList<>();
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot valueRes : dataSnapshot.getChildren()){
User user = valueRes.getValue(User.class);
mUserList.add(user);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
and below is the error i'm getting from the above code
com.google.firebase.database.DatabaseException: Expected a List while deserializing, but got a class java.util.HashMap
The User class consist of an arraylist of accounts!
It seems like you have a List<UserAccount> accounts field in your User class. While the data under accounts may look like a list to you at first glance, it is actually a Map in the database: a set of key/value pairs (the -Md7...` being the key).
So you'll want to change the type to:
Map<String, UserAccount> accounts

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.

firebase orderByChild() with specified child key doesnt work

I'm trying to get data which has current user uid and sort by time, but somehow my query brings data which has other uid as well
This is my query
FirebaseDatabase.getInstance().getReference().child("posts").orderByChild("uid_timestamp/"+uid).limitToLast(12)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
items.clear();
for (DataSnapshot item : dataSnapshot.getChildren()) {
items.add(item.getValue(PostModel.class));
Log.d("checking","writerUid "+item.getValue(PostModel.class).writerUid);
}
This is my database
So the writerUid is in uid_timestamp with the time. Am I using wrong child key? I need your help!

android firebase database: how to get all nodes that are in a set of values

I am trying to retrieve a list of friends for a user so I can display them in a list view. The friends and user info is structured like this in my firebase database:
So basically, I want to take the user ids listed in the friends part and query my users data to get all the info under every node that is in that set of user ids. How can I achieve this using the android firebase database sdk querying? I would like to be able to retrieve all the users in a single database query.
Thanks.
You cannot get that data in single query, you need to query your database twice. This is a common practice when it comes to Firebase. Assuming that friends and users nodes are direct childs of your Firebase root, to achieve this, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference friendIdRef = rootRef.child("friends").child(friendId)
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String key = ds.getKey();
DatabaseReference usersRef = rootRef.child("users").child(key);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dSnapshot : dataSnapshot.getChildren()) {
String username = dSnapshot.child("username").getValue(String.class);
Log.d("TAG", username);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
usersRef.addListenerForSingleValueEvent(eventListener);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
friendIdRef.addListenerForSingleValueEvent(valueEventListener);
It will print all user names of those particular users. One more thing to note, is that you don't need to add in your database those friends that have the value of false, only those with the value of true.

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.

Categories

Resources