I want to be able to retrieve everything that is currently held in a Firebase child folder. I write to the database like so;
private void commitPost() {
final String commentInput = commentText.getText().toString().trim();
commentProgress.setMessage("Posting");
commentProgress.show();
String uniqueId = UUID.randomUUID().toString();
commentDB.child(postID).child("Comments").child(uniqueId).setValue(commentInput);
commentProgress.dismiss();
finish();
}
I want to be able to read all values that are currently held in the child folder and then eventually display them in a ListView.
Database JSON;
"Engagement" : {
"-Kne46iBe6ooNFKTv_8w" : {
"Comments" : {
"c323835c-290c-44f3-8070-f9febf698ec9" : "none now!",
"stg15QKZFhNmTCYrgL5PtQ4wxJf2" : "testing"
},
"Likers" : {
"stg15QKZFhNmTCYrgL5PtQ4wxJf2" : "email#email.com"
}
To get the data only from a particular node, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference engagementRef = rootRef.child("Engagement").child("-Kne46iBe6ooNFKTv_8w").child("Comments");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String value = ds.getValue(String.class);
Log.d("TAG", value + ", ");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
engagementRef.addListenerForSingleValueEvent(eventListener);
Your output will be:
none now!, testing,
Related
I am developing an android application and now I am stuck in retrieving data from particular nodes like I want to retrieve only one value from each nodes. The database structure shows below.
How can I retrieve the second unique id that created by Firebase database?
First create a POJO class to get the values you want, it should be writen the same way as you have them in Firebase.
public class AppointmentsPojo {
private String appointmentStuts;
public AppointmentsPojo(){
}
public String getAppointmentStuts() {
return appointmentStuts;
}
public void setAppointmentStuts(String appointmentStuts) {
this.appointmentStuts = appointmentStuts;
}
}
Then just loop inside Appointments to get each appointmentStuts
mDatabase.child("Appointments").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Looping inside Appointments to get each appointmentsStuts
for(DataSnapshot snapshot: dataSnapshot.getChildren()){
AppointmentsPojo ap = snapshot.getValue(AppointmentsPojo.class);
//Getting each appointmentStuts
String appointmentStuts = ap.getAppointmentStuts();
//To get each father of those appointments
String key = snapshot.getKey();
Log.e("Data: " , "" + appointmentStuts );
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
Where mDatabase is
DatabaseReference mDatabase;
mDatabase = FirebaseDatabase.getInstance().getReference();
To get the value of appointmentStuts only from the first object, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("Appointments").child(PostKey).limitToFirst(1);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String appointmentStuts = ds.child("appointmentStuts").getValue(String.class);
Log.d(TAG, appointmentStuts);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage());
}
};
query.addListenerForSingleValueEvent(valueEventListener);
I have this data structure:
The red arrows points at animal IDs, and the blue arrow points at user IDs. Every user have one or many animals.
I have tried different methods for showing only the animals that have id that is stored in the current user node.
Example: If I have UID = 48onHXIxgDP465j5WW16oo7psNm2 (the first one in "users") I want to show the data from: "dog2" and "dog3".
Now iIhave the following code that gets snapshot from the "animals" node in the database, and then gets data from every child.
myAnimalRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
list = new ArrayList<AnimalCard>();
for(DataSnapshot dataSnapshot1 :dataSnapshot.getChildren()){
AnimalCard value = dataSnapshot1.getValue(AnimalCard.class);
AnimalCard animal = new AnimalCard();
String name = value.getName();
int age = value.getAge();
String url = value.getUrl();
animal.setName(name);
animal.setAge(age);
animal.setUrl(url);
list.add(animal);
}
recyclerViewSetAdapter();
progressDialog.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG1, "failed to read value: " + databaseError.toException());
}
});
How can get my code to filter out every animal that does not have their ID in the user node?
The reason I want to make the user get access with an UID stored in the database is because later on I want to make it so that multiple users can get access to the same animal.
To achieve this, you need to query your database twice. Please use the following code:
FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
String uid = firebaseUser.getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = usersRef.child("users").child(uid);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String aid = ds.getKey();
DatabaseReference animalRef = rootRef.child("animals").child(aid);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dSnapshot) {
int age = dSnapshot.child("age").getValue(Integer.class);
String name = dSnapshot.child("name").getValue(String.class);
String url = dSnapshot.child("url").getValue(String.class);
Log.d("TAG", age + " / " + name + " / " + url);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
animalRef.addListenerForSingleValueEvent(valueEventListener);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
uidRef.addListenerForSingleValueEvent(eventListener);
In which uid is the id of the logged-in user and aid is the id of the animal. Your output will be:
11 / dog1 / http...
12 / dog2 / http...
Hope you find this helpfull.!
Get Object in Your Model Class and Store that Object in List for Further user.!
You can get specific object as well simple using
mdatabaseRef.child("animals").orderByChild().equalTo("value")
and also you can add check on key by orderByKey()
private FirebaseAuth mAuth;
private FirebaseDatabase mdatabase;
private DatabaseReference mdatabaseRef;
mAuth = FirebaseAuth.getInstance();
mdatabase = FirebaseDatabase.getInstance();
mdatabaseRef = mdatabase.getReference();
ArrayList<User> allUserList = new ArrayList<>();
Array<Animal> allAnimalList=new ArrayList<>();
mdatabaseRef.child("animals").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
String key = childSnapshot.getKey();
Animal animal = childSnapshot.getValue(Animal.class);
allAnimalList.add(animal );
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
mdatabaseRef.child("users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
String key = childSnapshot.getKey();
User user = childSnapshot.getValue(User .class);
allUserList.add(user);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I ended up taking Alex Mamo's answer and tweak with a litte bit.
This is the code i'am using:
uid = currentUser.getUid();
mRootRef = FirebaseDatabase.getInstance().getReference();
final DatabaseReference myUserRef = mRootRef.child("users").child(uid);
Log.d(TAG1, uid);
myUserRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
list = new ArrayList<AnimalCard>();
for(DataSnapshot ds : dataSnapshot.getChildren()){
String aid = ds.getKey();
DatabaseReference myAnimalRef = mRootRef.child("animals");
Query query = myAnimalRef.orderByKey().equalTo(aid);
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds2 : dataSnapshot.getChildren()){
AnimalCard value = ds2.getValue(AnimalCard.class);
AnimalCard animal = new AnimalCard();
String name = value.getName();
int age = value.getAge();
String url = value.getUrl();
animal.setName(name);
animal.setAge(age);
animal.setUrl(url);
list.add(animal);
}
recyclerViewSetAdapter();
progressDialog.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
The main difference is that i'am using a query to filter out every Animal that does not have the aID that the currentUser have.
I want to retrieve all my datas and store each specific pushID into a button.
First question, how to get the keys of my push?
Second qustion, after getting the values, i want to store each ID into a button so i can update it. How?
could you get a JsonObject and then:
Set<Map.Entry<String, JsonElement>> entries = responseBody.entrySet();
List<FeedRow> rowList = new LinkedList<>();
for (Map.Entry<String, JsonElement> entry : entries) {
String key = entry.getKey());
String value = responseBody.get(entry.getKey()).toString();
}
then save in a list.
with a recyclerview,
1. add buttons with this list
2. addOnClickListener in each button
Try this:
FirebaseDatabase database = FirebaseDatabase.getInstance();
database.getReference()
.child("myfirstfirebaseproject-8f271")
.child("all-user-dishes")
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Log.v("KEY", "this is your key"+snapshot.getKey());
Log.v("VALUE", "this is your value"+snapshot.getValue());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
To get the data, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference yourRef = rootRef.child("all-user-dishes");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String dishName = ds.child("dishName").getValue(String.class);
String dishPrice = ds.child("dishPrice").getValue(String.class);
Log.d("TAG", dishName + " / " + dishPrice);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
yourRef.addListenerForSingleValueEvent(eventListener);
The output will be:
Luncheeon Meat / 150
Fruit Salad / 50
Sardines / 80
databaseQuestion = FirebaseDatabase.getInstance().getReference("users").child(KrgDOh_GnwpIons_r9Q);
databaseQuestion.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// System.out.println("VAL"+dataSnapshot.getValue());
//clearing the previous artist list
usersQuestions.clear();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
//iterating through all the nodes
//getting artist
System.out.println("VAL"+postSnapshot.getValue());
User user = postSnapshot.getValue(User.class);
//adding artist to the list
usersQuestions.add(user);
}
//creating adapter
QuestionUserList userQuestionsAdapter = new QuestionUserList(getActivity(), usersQuestions);
//attaching adapter to the listview
questionsList.setAdapter(userQuestionsAdapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I am facing the following error
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type
I want to fetch the data and display it in Listview. Please help out.
Assuming that users node is the direct child of Firebase root, to get those values, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("users");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String name = ds.child("name").getValue(String.class);
String question = ds.child("question").getValue(String.class);
String userId = ds.child("userId").getValue(String.class);
Log.d("TAG", address + " / " + question + " / " + userId);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
usersRef.addListenerForSingleValueEvent(eventListener);
Having those values, you can create a new object of your class as add it to questionsList list. Also don't forget to declare that list inside the onDataChange() method, otherwise it will be null.
Hope it hels.
I'm developing an application for Android that uses firebase.
The application has Users and each user has Friends.
users: {
one: {
name: Mark,
friends: {
two: true,
three: true
},
two: {
name: Carl
},
three: {
name: Gustav
}
}
In this example, Mark has two friends (Carl and Gustav), the other two don't have friends.
I want to get a Mark's Friends List.
String userId = "one";
DatabaseReference friendsDb = db.getReference("users").child(userId).child("friends");
final DatabaseReference usersDb = db.getReference("users");
ValueEventListener friendsListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
GenericTypeIndicator<LinkedHashMap<String,Boolean>> t = new GenericTypeIndicator<LinkedHashMap<String,Boolean>>() {};
LinkedHashMap<String,Boolean> tDataset = dataSnapshot.getValue(t);
users.clear();
for( String userId : tDataset.keySet() ) {
usersDb.child(userId).addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
// how to return the user???
// users.add(user);
}
});
}
mAdapter.notifyDataSetChanged();
}
};
friendsDb.addValueEventListener(friendsListener);
Am I using a correct approach about data modeling and indexes?
How is it supposed to give me back the user list that I need?
I understand that listening to a resource it is an async operation, is there a way to get the values that I need in one shot?
Any help will be appreciated! Thanks!
EDIT
Solution proposed by Frank van Puffelen it's correct in the concept but it's not correctly implemented. The concept is to call the mAdapter.notifyDataSetChanged(); when all the children has been retrieved from firebase db. But it have to check the dimension of the first snapshot, intead of the second, as below.
DatabaseReference friendsDb = db.getReference("users").child(userId).child("friends");
final DatabaseReference usersDb = db.getReference("users");
ValueEventListener friendsListener = new ValueEventListener() {
#Override
public void onDataChange(final DataSnapshot dataSnapshot) {
GenericTypeIndicator<HashMap<String,Boolean>> t = new GenericTypeIndicator<HashMap<String,Boolean>>() {};
HashMap<String,Boolean> tDataset = dataSnapshot.getValue(t);
final int usersSize = tDataset.size();
users.clear();
for( String userId : tDataset.keySet() ) {
usersDb.child(userId).addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
users.add(user);
if (users.size() == usersSize) {
mAdapter.notifyDataSetChanged();
}
}
});
}
}
};
friendsDb.orderByKey().addValueEventListener(friendsListener);
There is no Firebase equivalent of SQLs WHERE id IN (1,2,3). Performance-wise that is not needed, since Firebase pipelines the requests.
You code looks fine to me, except that you're not adding the user to the list. I expect that you're having trouble defining the "exit condition" for that loop, which is:
ValueEventListener friendsListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
GenericTypeIndicator<LinkedHashMap<String,Boolean>> t = new GenericTypeIndicator<LinkedHashMap<String,Boolean>>() {};
LinkedHashMap<String,Boolean> tDataset = dataSnapshot.getValue(t);
users.clear();
for( String userId : tDataset.keySet() ) {
usersDb.child(userId).addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
users.add(user);
if (users.size() == dataSnapshot.getChildrenCount()) {
mAdapter.notifyDataSetChanged();
}
}
});
}
}
};
Try arranging your data this way:
users: {
one: {
name: Mark
},
two: {
name: Carl
},
three: {
name: Gustav
}
},
friends : {
Mark : {
two : true,
three : true
}
}