I am trying to get a parent value of a field in Firebase database along with its children.
for clarification:
I want to loop through the Snapshot to find the user who want to login by his or her ID, after that I want to get the parent of that id (i.e. is the user female or male) after that I want to get the canton and name.
so what I am doing is:
database=FirebaseDatabase.getInstance();
rootRef = database.getReference();
users = rootRef.child("Users");
and then
users.orderByChild("name").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child : dataSnapshot.getChildren()) {
if (child.getValue().equals(curUser.getUid())) {
String gender = child.getKey().toString();
currentPolUser.setuGender(gender);
currentPolUser.setuName(child.child("Name").getValue().toString());
Log.d("FirebaseUsers", "SUCCESSSSSS: "+currentPolUser.getuName() + " " + currentPolUser.getuGender());
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
The problem is child.getValue() returns an object that can't be compared to the User id string.
Try this:
ref.child("Users").orderByChild("name").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child : dataSnapshot.getChildren()) {
String gender = child.getKey();
for(DataSnapshot finalChild : child.getChildren()){
if (finalChild.getKey().equals(curUser.getUid())) {
HashMap<String, Object> map = (HashMap<String, Object>) finalChild.getValue();
String name = (String) map.get("name");
currentPolUser.setuGender(gender);
currentPolUser.setuName(name);
Log.d("FirebaseUsers", "SUCCESSSSSS: "+currentPolUser.getuName() + " " + currentPolUser.getuGender());
Log.e("TTT", name);
}
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Related
I want to compare text with data from firebase. Below is my code and it reads name only from ing01. but actually i want it to read from all ingredient data, not only ing01. Please help me, thank you.
final String dataCompare=sb.toString();//.replaceAll("\\s+","");
databaseReference = firebaseDatabase.getInstance().getReference().child("ingredients");//.child("ing01").child("iName");
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()){
String iName = ds.child("iName").getValue(String.class);
if(dataCompare.equals(iName)){
mResultEt.setText(dataCompare);
mStatusEt.setText("OK");
mStatusEt.setTextColor(Color.GREEN);
}
else{
mResultEt.setText(dataCompare);
mStatusEt.setText("Not OK");
mStatusEt.setTextColor(Color.RED);
}
}
Check this:
FirebaseDatabase.getInstance().getReference().child("ingredients").addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
String iName = childSnapshot.child("iName").getValue(String.class);
//Implement your logic here
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
}
);
Here you will get all the ingredients and through iteration you get the iName.
But According your implementation logic. It's useless to get all the ingredients, rather you can get the specific ingredient matching your compare query. Try like below:
FirebaseDatabase.getInstance().getReference().child("ingredients").orderByChild("iName").equalTo(dataCompare).addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.hasChildren()) {
mResultEt.setText(dataCompare);
mStatusEt.setText("OK");
mStatusEt.setTextColor(Color.GREEN);
} else {
mResultEt.setText(dataCompare);
mStatusEt.setText("Not OK");
mStatusEt.setTextColor(Color.RED);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
}
);
Instead of firebaseDatabase.getInstance().getReference().child("ingredients").child("ing01").child("iName");, use firebaseDatabase.getInstance().getReference().child("ingredients"); for getting all ingredients
you can used a third party library like: Angularfire here is there official link: https://github.com/angular/angularfire
final String dataCompare=sb.toString();
databaseReference = firebaseDatabase.getInstance().getReference().child("ingredients");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String iName1 = dataSnapshot.child("ing01").child("iName");
String iName2 = dataSnapshot.child("ing02").child("iName");
//now here you can compare both the iName values with the dataCompare object.
}
}
**** EDIT ****
final String dataCompare=sb.toString();
Log.d("DataCompare: ", dataCompare);
databaseReference = firebaseDatabase.getInstance().getReference().child("ingredients");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.getChildren() == null) {
Log.d(TAG, "onDataChange: snapshot has no children");
} else {
int i = 1;
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String iName = ds.child("ing0" + i++).child("iName").getValue();
// if this doesn't work try this --
// String iName = ds.child("iName").getValue();
Log.d(TAG, "name value: " + iName);
if (iName.equals(dataCompare)) {
Log.d(TAG, "onDataChange: string equals");
} else {
Log.d(TAG, "onDataChange: strings are not equal");
}
}
}
}
}
Inside the onDataChange() method I wrote :-
String iName = ds.child("ing0" + i++).child("iName").getValue();
here we are reading the child "ing01" (in the first iteration of the loop) of the datasnapshot which is currently at "ingredients", and then we read "iName" and its value into iName string object.
for each loop will do this for all the children of the dataSnapshot which means for all the data you have in your firebase database.
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 want to get data according to user's ranking. First order by user's points and get users position in node. But I can't think of the way to implement this.
First This is my firebase 'users' node
Maybe It will be like 'databaseRef.child("users").orderByChild("points")...'
I don't know from here.
ps. It's not get nth item. It's 'where is the item' ( item's nth )
Thank you!
This can be done by adding a ctr in you dataSnapshot loop
myRef = FirebaseDatabase.getInstance().getReference().child("users");
final Query query = myRef.orderByChild("points");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int total = dataSnapshot.getChildrenCount();
int i = 0;
// loop through dataSnapshot
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
String nickName = childSnapshot.child("nickName").getValue(String.class);
if (nickName.equals(mUser.getNickName()) {
//when nickName would match
int userPlace = total - i;
int points = childSnapshot.child("points").getValue(Interger.class);
//do something here
break;
} else {
i++;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Kindly read
Retrieving Data.
How Data is Ordered
The callback function receives a DataSnapshot, which is a snapshot of
the data. A snapshot is a picture of the data at a particular database
reference at a single point in time. Calling val() / getValue() on a
snapshot returns the a language-specific object representation of the
data. If no data exists at the reference's location, the snapshot's
value is null.
If you want to get all points then check this LOGIC.
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("products");
ref.addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
ArrayList<Integer> points = new ArrayList<>();
for (Map.Entry<String, Object> entry : products.entrySet()){
Map singleUser = (Map) entry.getValue();
points.add((Integer) singleUser.get("points"));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
//handle databaseError
}
});
I solve this problem. Android_K.Doe's answer is right. I add some code in his code. Because Firebase database does not give descending query.
final Query query = databaseReference.child("users").orderByChild("points");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int i = 0;
int all = (int) dataSnapshot.getChildrenCount();
Log.d(TAG, "all: " + all);
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String nickName = ds.child("nickName").getValue(String.class);
if (nickName.equals(user.getNickName())) {
Log.d(TAG, "nickName: " + user.getNickName());
int userPlace = i;
Log.d(TAG, "position: " + userPlace);
myInfoRankingNumTxt.setText(Integer.toString(all - (i)) + "위");
break;
} else {
i++;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
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.
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.